C++变长std::tuple提取元素类型时类型匹配错误问题
std::tuple元素类型提取编译错误解决方案
错误原因
两处static_assert失败的核心原因是没有正确获取C++类型萃取元函数的结果类型:
- 针对第一个断言:
std::tuple_element是用于提取tuple元素类型的模板结构体,你直接使用它的实例类型和int做类型匹配自然会失败,需要访问其内部嵌套的type成员才能拿到实际的元素类型。 - 针对第二个断言:
std::remove_reference同样是类型萃取模板结构体,也需要访问其内部的type成员才能得到移除引用修饰后的目标类型。
修正代码
兼容C++11的写法
#include <tuple> #include <type_traits> using TestTuple = std::tuple<int>; template <std::size_t I = 0, typename... Tp> inline typename std::enable_if<I == sizeof...(Tp), void>::type foo(std::tuple<Tp...> &) {} template <std::size_t I = 0, typename... Tp> inline typename std::enable_if<(I < sizeof...(Tp)), void>::type foo(std::tuple<Tp...> &output) { // 取tuple_element的type成员获取实际元素类型 using ValueType = typename std::tuple_element<I, std::tuple<Tp...>>::type; static_assert(std::is_same<ValueType, int>::value, "Should be true"); // 取remove_reference的type成员获取移除引用后的类型 using ValueType2 = typename std::remove_reference<decltype(std::get<I>(output))>::type; static_assert(std::is_same<ValueType2, int>::value, "Should be true"); // 递归处理下一个元素 foo<I+1>(output); } void bar() { TestTuple t; foo(t); }
C++14及以上简化写法
可以直接使用标准库提供的_t别名省略typename和::type的书写:
using ValueType = std::tuple_element_t<I, std::tuple<Tp...>>; using ValueType2 = std::remove_reference_t<decltype(std::get<I>(output))>;
内容的提问来源于stack exchange,提问作者Morten B.
相关产品推荐
相关产品推荐

