使用C ++(gcc 4.8.3)我有两种类型(T1
和T2
),它们具有typeid(T1).name()
和typeid(T2).name()
相同的奇怪属性但
std::is_same<T1, T2>::value
为false
。
怎么会这样?我怎样才能进一步调查以说明原因可能是什么?
答案 0 :(得分:14)
忽略多态,T
为您提供一个表示表达式静态类型的对象。但是在表达类型方面有一些被忽略的元素。来自[expr]:
如果表达式最初具有类型“
T
的引用”(8.3.2,8.5.3),则类型将在T
之前调整为T
进一步的分析。 [...]如果prvalue最初的类型为“ cvT
”,其中int
是 cv - 不合格的非类,非数组类型,类型 在进行任何进一步分析之前,将表达式调整为const int
。
因此,只有顶级 cv - 限定或引用不同的任何类型都会产生相同的typeid。例如,类型int&
,volatile const int&&
,typeid()
typeid(T) == typeid(U) <==> std::is_same<T, U>
等等都会为您提供相同的typeid(T) == typeid(U) <==> std::is_same<expr_type<T>, expr_type<U>>
。
基本上,您最初的思考过程是:
template <class T>
using expr_type = std::remove_cv_t<std::remove_reference_t<T>>;
但正确的等同是:
{{1}}
其中:
{{1}}
答案 1 :(得分:6)
typeid
忽略所有cv限定符:
在所有情况下,typeid都会忽略cv限定符(即typeid(T)== typeid(const T))
这意味着typeid
会忽略所有引用&
和const
(仅举几例)。
int i = 0;
const int&& j = 1;
if (typeid(i).hash_code() == typeid(j).hash_code()) //returns true
std::cout << "typeid(int) == typeid(const int&&)";
请注意,为了比较2 typeid
s,您必须使用typeid(T).hash_code()
或std::type_index(typeid(T))
,因为只有这2个函数才能保证2个typeid
s相同会是一样的。例如,比较参考文献没有这种保证。
<小时/> 正如@Yakk所提到的,您可以使用不能保证相同类型的typeid表达式的所有评估都会引用相同的std :: type_info实例,尽管那些type_info对象的std :: type_info :: hash_code将是相同的,因为它们将是相同的他们的std :: type_index。
std::remove_reference
和std::remove_cv
来获得您想要的行为。
std::remove_reference
删除了T的所有引用,std::remove_cv
删除了所有const
和volatile
限定符。您应该将T
传递给这些函数,然后再将其传递给std::is_same
,以便std::is_same
仅比较T1
和T2
的基础类型(如果有)。