2016-07-21 12 views
2

ich einen Code wie haben:GCC Tupel "ungültige Verwendung von unvollständigen Typ"

#include <tuple> 
#include <utility> 
#include <iostream> 

template<int ...> struct seq {}; 
template<int N, int ...S> struct gens : gens<N - 1, N - 1, S...> {}; 
template<int ...S> struct gens<0, S...> { typedef seq<S...> type; }; 

template<typename ValueType> 
bool get_value(ValueType& value, int index) { 
    //just for test 
    value = 100; 
    return true; 
} 


template<> 
bool get_value(const char*& value, int index) { 
    //just for test 
    value = "Hello?"; 
    return true; 
} 

template<int index, std::size_t remaining, typename... Args> 
struct arg_helper { 
    inline static bool 
    get_args(std::tuple<Args...>& t) { 
     if (get_value(std::get<index>(t), index)) { 
      return arg_helper<index + 1, remaining - 1, Args...>::get_args(t); 
     } 
     else { 
      return false; 
     } 
     return true; 
    } 
}; 


template<std::size_t index, typename... Args> 
struct arg_helper<index, 0, Args... > { 
    inline static bool 
    get_args(std::tuple<Args...>& t) { 
     return true; 
    } 
}; 


template<typename R, typename... Args, int ...S> 
void callFunc(R(func)(Args...), seq<S...>, std::tuple<Args...>& tup) { 
    func(std::get<S>(tup) ...); 
} 

template<typename R, typename... Args> 
void TestFunc(R(func)(Args...)) { 
    std::tuple<Args...> tup; 

    arg_helper<0, sizeof ...(Args), Args...>::get_args(tup); 

    callFunc(func, typename gens<sizeof...(Args)>::type(), tup); 
} 

static void FuncA(int test, const char* str) { 
    std::cout << "test func" << test << str << std::endl; 
} 


int main() { 
    TestFunc(FuncA); 
    return 0; 
} 

Es auf MSVC2013 laufen kann, aber Compiler-Fehler auf GCC auf der Linie:

arg_helper<0, sizeof ...(Args), Args...>::get_args(tup); 

Was bin ich falsch machen?

BTW: Ich weiß iterate over tuple es auf gcc laufen kann, aber die Arbeit scheint nicht für MSVC2013

+0

Was ist die vollständige Fehlermeldung erhalten Sie? – NathanOliver

+0

@NathanOliver http://coliru.stacked-crooked.com/a/e6e3be97c63bac4c kann hier versuchen. – ejkoy

+0

Slighty Off-Topic, aber: achten Sie darauf, [bei Template-Spezialisierungen vorsichtig zu sein] (http://www.gotw.ca/publications/mill17.htm), da diese nicht überladen. Nehmen wir an, Sie sollten eine andere Template-Funktion implementieren, die 'bool get_value (ValueType & value, int index)' 'überlädt, sagen wir' bool get_value (ValueType * & value, int index) '. Für einen Aufruf von 'get_value' mit einem ersten Argument vom Typ' char * 'würden wir erwarten, dass die Spezialisierung' bool get_value (const char * & value, int index) 'in der Überladungsauflösung gewählt wird, aber abhängig von der Reihenfolge des Vorkommens der Definition der überladenen ... – dfri

Antwort

2

Es scheint zu sein, weil Sie int und size_t in Ihrem Nicht-Typ Template-Parameter sind unpassende. Ändern sie alle über size_t und du bist in Ordnung:

Demo (GCC)

Demo (Clang)

#include <tuple> 
#include <utility> 
#include <iostream> 

template<size_t ...> struct seq {}; 
template<size_t N, size_t ...S> struct gens : gens<N - 1, N - 1, S...> {}; 
template<size_t ...S> struct gens<0, S...> { typedef seq<S...> type; }; 

template<typename ValueType> 
bool get_value(ValueType& value, size_t index) { 
    //just for test 
    value = 100; 
    return true; 
} 


template<> 
bool get_value(const char*& value, size_t index) { 
    //just for test 
    value = "Hello?"; 
    return true; 
} 

template<size_t index, std::size_t remaining, typename... Args> 
struct arg_helper { 
    static bool 
    get_args(std::tuple<Args...>& t) { 
     if (get_value(std::get<index>(t), index)) { 
      return arg_helper<index + 1, remaining - 1, Args...>::get_args(t); 
     } 
     else { 
      return false; 
     } 
     return true; 
    } 
}; 

template<std::size_t index, typename... Args> 
struct arg_helper<index, 0, Args... > { 
    static bool 
    get_args(std::tuple<Args...>& t) { 
     return true; 
    } 
}; 


template<typename R, typename... Args, size_t ...S> 
void callFunc(R(func)(Args...), seq<S...>, std::tuple<Args...>& tup) { 
    func(std::get<S>(tup) ...); 
} 

template<typename R, typename... Args> 
void TestFunc(R(func)(Args...)) { 
    std::tuple<Args...> tup; 

    arg_helper<0, sizeof ...(Args), Args...>::get_args(tup); 

    callFunc(func, typename gens<sizeof...(Args)>::type(), tup); 
} 

void FuncA(int test, const char* str) { 
    std::cout << "test func" << test << str << std::endl; 
} 


int main() { 
    TestFunc(FuncA); 
    return 0; 
} 
+0

oops! weine nach gcc Fehlermeldung. danke für die Hilfe! – ejkoy

+1

Vielleicht auch hier erwähnenswert: Es gibt wirklich keinen Grund, (die voll spezialisierte Funktion) "get_value (const char * & value, size_t index)" eine Template-Spezialisierung zu sein: es könnte auch eine Nicht-Template-Funktion sein. – dfri

Verwandte Themen