2010-04-25 11 views
5

Ich spiele herum mit variadische Vorlagen (gcc 4.5) und schlagen Sie dieses Problem:Ist Boost.Tuple kompatibel mit C++ 0x variadic Vorlagen?

template <typename... Args> 
boost::tuple<Args...> 
my_make_tuple(Args... args) 
{ 
    return boost::tuple<Args...>(args...); 
} 

int main (void) 
{ 
    boost::tuple<int, char> t = my_make_tuple(8, 'c'); 
} 

GCC Fehlermeldung:

sorry, unimplemented: cannot expand 'Arg ...' into a fixed-length argument list 
In function 'int my_make_tuple(Arg ...)' 

Wenn ich jedes Vorkommen von boost::tuple durch std::tuple ersetzen, es fein kompiliert.
Gibt es ein Problem bei der Boost-Tupel-Implementierung? Oder ist das ein GCC-Bug?

Ich muss für jetzt mit Boost.Tuple bleiben. Kennen Sie eine Problemumgehung?
Danke.

+0

http://stackoverflow.com/questions/1989552/gcc-error-with-variadic-templates-sorry-unimplemented-cannot-expand-identif? – kennytm

Antwort

7

Es scheint nicht zu erweitern Args... zu T1, T2, T3, ..., T9 wie Boost es hat.

Als Abhilfe kann verwenden Konstrukte, die diese Erweiterung nicht benötigen:

#include <boost/tuple/tuple.hpp> 

template <typename... Args> 
auto my_make_tuple(Args... args) -> decltype(boost::make_tuple(args...)) 
{ 
    return {args...}; 
} 

int main (void) 
{ 
    boost::tuple<int, char> t = my_make_tuple(8, 'c'); 
} 

Eine weitere Option könnte die Erweiterung manuell zu tun, zu sehen, dass boost::tuple-10 Argumente unterstützt werden.

#include <boost/tuple/tuple.hpp> 

template <unsigned, class, class...> struct nth_argument; 

template <unsigned N, class Default, class T, class... Args> 
struct nth_argument<N, Default, T, Args...> 
{ 
    typedef typename nth_argument<N - 1, Default, Args...>::type type; 
}; 

template <class Default, class T, class... Args> 
struct nth_argument<0, Default, T, Args...> 
{ 
    typedef T type; 
}; 

template <unsigned N, class Default> 
struct nth_argument<N, Default> 
{ 
    typedef Default type; 
}; 

template <typename ...Args> 
struct tuple_from_var_template 
{ 
    typedef boost::tuple< 
     typename nth_argument<0, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<1, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<2, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<3, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<4, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<5, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<6, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<7, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<8, boost::tuples::null_type, Args...>::type, 
     typename nth_argument<9, boost::tuples::null_type, Args...>::type 
    > type; 
}; 

template <typename... Args> 
typename tuple_from_var_template<Args...>::type my_make_tuple(Args... args) 
{ 
    return typename tuple_from_var_template<Args...>::type(args...); 
} 

int main (void) 
{ 
    boost::tuple<int, char> t = my_make_tuple(8, 'c'); 
}