2010-04-25 2 views
5

я играл с переменным числом шаблонов (GCC 4.5) и нажмите эту проблему:Является ли Boost.Tuple совместимым с C++ 0x вариантными шаблонами?

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'); 
} 

НКУ сообщение об ошибке:

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

Если я заменить каждое вхождение boost::tuple по std::tuple, он отлично компилируется.
Есть ли проблема в реализации кортежа форматирования? Или это ошибка gcc?

На данный момент я должен придерживаться Boost.Tuple. Знаете ли вы какое-нибудь обходное решение?
Спасибо.

+0

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

ответ

7

Похоже, что не расширяется Args... до T1, T2, T3, ..., T9, поскольку Boost имеет его.

В качестве временного решения, использовать конструкции, которые не требуют такого расширения:

#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'); 
} 

Другим вариантом может быть сделать расширение вручную, видя, что boost::tuple поддерживает до 10 аргументов.

#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'); 
}