【发布时间】:2016-09-14 14:11:17
【问题描述】:
我想以某种方式使用成员函数模板迭代一个元组(以便稍后从给定的模板类型T 创建一个新类型的元组)。
但是,没有使用中断条件(函数),所以我得到了这个错误:
不完整类型的无效使用:'class std::tuple_element >'
问题似乎是,即使元组的N == size,std::tuple_element_t 被评估为N != size,而不是作为 SFINAE 处理。
两个示例都显示了不同的无效解决方案。我哪里错了?
注意:使用is_same 评估的函数被省略以最小化示例。
#include <type_traits>
#include <tuple>
template<typename...Ts>
struct A
{
using tuple = std::tuple<Ts...>;
static constexpr std::size_t size = sizeof...(Ts);
template<typename T, std::size_t N = 0, typename std::enable_if_t<N == size>* = nullptr>
int get()
{
return 0;
}
template<typename T, std::size_t N = 0, typename std::enable_if_t<N != size && !std::is_same<T, std::tuple_element_t<N, tuple>>::value>* = nullptr>
int get()
{
return get<T, N + 1>() - 1;
}
};
int main()
{
A<int, float, double, float, float> a;
return a.get<char>();
}
#include <type_traits>
#include <tuple>
template<typename...Ts>
struct A
{
using tuple = std::tuple<Ts...>;
static constexpr std::size_t size = sizeof...(Ts);
template<typename T, std::size_t N = 0>
std::enable_if_t<N == size, int> get()
{
return 0;
}
template<typename T, std::size_t N = 0>
std::enable_if_t<N != size && !std::is_same<T, std::tuple_element_t<N, tuple>>::value, int> get()
{
return get<T, N + 1>() - 1;
}
};
int main()
{
A<int, float, double, float, float> a;
return a.get<char>();
}
一种解决方法是使用第三个函数来评估直到 sizeof tuple - 2 而不是评估 sizeof tuple - 1,但这真的有必要吗?
#include <type_traits>
#include <tuple>
template<typename...Ts>
struct A
{
using tuple = std::tuple<Ts...>;
static constexpr std::size_t size = sizeof...(Ts);
template<typename T, std::size_t N = 0, typename std::enable_if_t<(N == size - 1) && std::is_same<T, std::tuple_element_t<N, tuple>>::value>* = nullptr>
int get()
{
return 1;
}
template<typename T, std::size_t N = 0, typename std::enable_if_t<(N == size - 1) && !std::is_same<T, std::tuple_element_t<N, tuple>>::value>* = nullptr>
int get()
{
return 2;
}
template<typename T, std::size_t N = 0, typename std::enable_if_t<(N < size - 1) && !std::is_same<T, std::tuple_element_t<N, tuple>>::value>* = nullptr>
int get()
{
return get<T, N + 1>() - 1;
}
};
int main()
{
A<int, float, double, float, float> a;
return a.get<char>();
}
【问题讨论】:
-
最后一个索引是
size-1,不是size,所以N应该和值size-1比较 -
我知道,所以最后一个函数(终止)应该是元素大小的一个索引(这是因为 N != size)。如果对于 N
标签: c++ templates tuples c++14 sfinae