我找不到类似的问题...
我认为有两种“简单”的方法可以在编译时获取元组的第I个元素的类型(如果我错了,请纠正我):
using TI1 = typename std::tuple_element<I, Tuple>::type;
using TI2 = decltype(std::get<I>(Tuple{}));
实际上,如果我们通过typeid(...).name()
打印每个类型,则它们返回相同的值。
但是...当我比较这些条件时,std::is_same
返回false:
这是预期的吗?为什么?
using Tuple = std::tuple<float,double>;
constexpr size_t I = 0;
static_assert(std::is_same<typename std::tuple_element<I, Tuple>::type,
decltype(std::get<I>(Tuple{}))>::value, "different types" );
答案 0 :(得分:7)
std::get(std::tuple)
返回引用;也就是说,在其上使用decltype
,您将获得引用类型。
a)如果表达式的值类别为xvalue,则decltype产生
T&&
;
b)如果表达式的值类别为左值,则decltype产生T&
;
c)如果表达式的值类别是prvalue,则为decltype 产生T
。
在这种情况下,返回类型std::get<I>(Tuple{})
是右值引用,然后std::get<I>(Tuple{})
是xvalue expression,
函数调用或重载的运算符表达式,其返回类型是对对象的右值引用,例如
std::move(x)
;
然后decltype(std::get<I>(Tuple{}))
将是T&&
,即float&&
;与typename std::tuple_element<I, Tuple>::type
(即float
)不同。
使用std::remove_reference
可以得到想要的东西。例如
static_assert(std::is_same<typename std::tuple_element<I, Tuple>::type,
std::remove_reference_t<decltype(std::get<I>(Tuple{}))>>::value, "different types" );
关于typeid
为什么给出相同结果的原因,
(重点是我的)
1)引用表示类型类型的
std::type_info
对象。 如果类型是引用类型,则结果引用表示引用类型的std::type_info
对象。
这意味着typeid(float&&) == typeid(float)
始终是true
。