本文介绍了Boost.Tuple是否与C ++ 0x可变参数模板兼容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我在玩可变模板(gcc 4.5),遇到这个问题:

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

 抱歉,未实现:无法将Arg ...展开成固定长度的参数列表
在函数'int my_make_tuple(Arg ...)'

如果我替换每次出现的 boost :: tuple std :: tuple ,它编译得很好。

boost元组实现有问题吗?或者是一个gcc bug?



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

谢谢。

解决方案

C $ c> Args ... 到 T1,T2,T3,...,T9 b
$ b

作为解决方法,使用不需要此扩展的构造:

  #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,默认>
{
typedef默认类型;
};

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< :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
>类型;
};

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



I was playing around with variadic templates (gcc 4.5) and hit this problem :

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 error message :

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

If I replace every occurrence of boost::tuple by std::tuple, it compiles fine.
Is there a problem in boost tuple implementation? Or is this a gcc bug ?

I must stick with Boost.Tuple for now. Do you know any workaround ?
Thanks.

解决方案

It doesn't seem to like expanding Args... to T1, T2, T3, ..., T9 as Boost has it.

As a workaround, use constructs that don't require this expansion:

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


Another option might be to do the expanding manually, seeing that boost::tuple supports up to 10 arguments.

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

这篇关于Boost.Tuple是否与C ++ 0x可变参数模板兼容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 10:52