Boost.Tuple est compatible avec C ++ 0x variadique modèles?
-
01-10-2019 - |
Question
Je jouais avec des modèles variadique (gcc 4.5) et a frappé ce problème:
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 message d'erreur:
sorry, unimplemented: cannot expand 'Arg ...' into a fixed-length argument list
In function 'int my_make_tuple(Arg ...)'
Si je remplace toutes les occurrences de boost::tuple
par std::tuple
, il compile bien.
Y at-il un problème dans la mise en œuvre de tuple boost? Ou est-ce un bug de gcc?
Je dois en tenir à Boost.Tuple pour l'instant. Connaissez-vous des solution de contournement?
Merci.
La solution
Il ne semble pas que l'expansion Args...
à T1, T2, T3, ..., T9
comme Boost a.
Pour contourner ce problème, les constructions d'utilisation qui ne nécessitent pas cette extension:
#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');
}
Une autre option pourrait consister à faire l'expansion manuellement, en voyant que les supports de boost::tuple
jusqu'à 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');
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow