2010-04-25 98 views
5

我和可变参数模板(GCC 4.5)打出去,撞上这个问题:Boost.Tuple与C++ 0x variadic模板兼容吗?

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错误消息:

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

如果我通过std::tuple取代boost::tuple每一次出现,它编译罚款。
boost元组实现中是否存在问题?或者这是一个gcc错误?

现在我必须坚持使用Boost.Tuple。你知道任何解决方法吗?
谢谢。

+0

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

回答

7

它似乎并不喜欢扩大Args...T1, T2, T3, ..., T9为加速有它。

作为一种变通方法,使用不需要这种扩张结构:

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