我正在尝试删除元组的最后一个元素。当我在元组中只有一个要删除的元素时,它可以工作。但是当我有不止一个的时候,事情就出了问题。我不明白为什么这不管用。以下是我所犯的错误:
prog.cpp:函数‘
int main()’: prog.cpp:24:22:错误:嵌套名称说明符中使用的不完全类型‘remove_last<std::tuple<int, int> >’ prog.cpp:24:22:错误:嵌套名称说明符中使用的不完全类型‘remove_last<std::tuple<int, int> >’ prog.cpp:24:70:错误:模板参数1无效
#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"
);
}当我在其中一个专门化中使模板参数非变量化时,错误就消失了。但是,这就变成了一个专门化的过程,它只处理一个包含两个元素的元组--而不是我想要的。我怎样才能使它与各种参数一起工作呢?换句话说,当元组中有多个元素时,我如何使它工作呢?
发布于 2013-04-28 21:48:11
问题是,参数包是贪婪的,而且--因为它是第一位的--在执行类型推导时会吃掉序列中的所有类型,包括您希望从Args...中排除的Args...。
您可以这样定义变量专门化(请注意,参数包现在在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...>;
};发布于 2018-08-12 02:58:14
另一种解决方案需要C++14或更新版本:
#include <tuple>
template<class Tuple>
struct remove_last;
template<>
struct remove_last<std::tuple<>>; // Define as you wish or leave undefined
template<class... Args>
struct remove_last<std::tuple<Args...>>
{
private:
using Tuple = std::tuple<Args...>;
template<std::size_t... n>
static std::tuple<std::tuple_element_t<n, Tuple>...>
extract(std::index_sequence<n...>);
public:
using type = decltype(extract(std::make_index_sequence<sizeof...(Args) - 1>()));
};
template<class Tuple>
using remove_last_t = typename remove_last<Tuple>::type;请参阅sequence
https://stackoverflow.com/questions/16268107
复制相似问题