我正在尝试删除元组的最后一个元素.当我在元组中只有一个元素要移除时,它可以工作.但是当我不止一个时,事情就出错了.我不明白为什么这不起作用.这些是我得到的错误:
prog.cpp: In function ‘
int main()
’:
prog.cpp:24:22: error: incomplete type ‘remove_last<std::tuple<int,int> >
’ used in nested name specifier
prog.cpp:24:22: error: incomplete type ‘remove_last<std::tuple<int,int> >
’ used in nested name specifier
prog.cpp:24:70: error: template argument 1 is invalid
#include <tuple> #include <type_traits> template <class T> struct remove_last; template <class T> struct remove_last<std::tuple<T>> { using type = std::tuple<>; }; template <class... Args,typename T> struct remove_last<std::tuple<Args...,T>> { using type = std::tuple<Args...>; }; int main() { std::tuple<int,int> var; static_assert( std::is_same<remove_last<decltype(var)>::type,std::tuple<int>>::value,"Values are not the same" ); }
当我在其中一个特化中使模板参数非变量时,错误消失了.但后来这变成了一个专门化,它只会处理一个有两个元素的元组 – 而不是我的目标.我怎样才能使用变量参数?换句话说,当元组中有多个元素时,如何才能使它工作?
解决方法
问题是参数包是贪婪的 – 并且 – 因为它是第一个 – 在执行类型推导时吃掉序列中的所有类型,包括你希望被遗漏在Args中的T ….
你可以用这种方式定义可变参数特化(注意参数包现在出现在std :: tuple< T,Args ...>中)的最后一个:
template <class T,class... Args> struct remove_last<std::tuple<T,Args...>> { using type = typename concat_tuple< std::tuple<T>,typename remove_last<std::tuple<Args...>>::type >::type; };
并以这种方式定义concat_tuple元函数:
template<typename,typename> struct concat_tuple { }; template<typename... Ts,typename... Us> struct concat_tuple<std::tuple<Ts...>,std::tuple<Us...>> { using type = std::tuple<Ts...,Us...>; };