我想用成员函数模板以某种方式迭代元组(以便稍后从给定的模板类型创建新类型的元组
T
).
无效使用了不完整的类型:“class std::tuple_element<0ul,标准::元组<>>'
问题似乎是,尽管
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>();
}
Live Example 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>
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>();
}
Live Example 2
一种解决方法是使用第三个函数计算sizeof tuple-2,然后计算sizeoftuple-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>();
}
Live Example 3