相同的typeid名称,但不是std :: is_same

Lud*_*ert 18 c++ c++11

使用C++(GCC 4.8.3)我有2种类型(T1T2),其具有奇怪的属性,typeid(T1).name()并且typeid(T2).name()是相同的,但 std::is_same<T1, T2>::valuefalse.

怎么可能?我如何进一步调查,告诉原因可能是什么?

Bar*_*rry 14

忽略多态,typeid()为您提供表示表达式的静态类型的对象.但是在表达类型方面有一些被忽略的元素.来自[expr]:

如果表达式最初具有"引用T" 类型(8.3.2,8.5.3),则T在进行任何进一步分析之前调整类型.[...]如果prvalue最初具有类型" cv T ",其中Tcv -unqualified非类非数组类型,则T在进行任何进一步分析之前调整表达式的类型.

因此,只有顶级cv资格或参考不同的任何类型都会产生相同的typeid.例如,类型int,const int,int& volatile const int&&,等一切给你相同的typeid().

基本上,您最初的思考过程是:

typeid(T) == typeid(U) <==> std::is_same<T, U>
Run Code Online (Sandbox Code Playgroud)

但正确的等价是:

typeid(T) == typeid(U) <==> std::is_same<expr_type<T>, expr_type<U>>
Run Code Online (Sandbox Code Playgroud)

哪里:

template <class T>
using expr_type = std::remove_cv_t<std::remove_reference_t<T>>;
Run Code Online (Sandbox Code Playgroud)


Rak*_*111 6

typeid 忽略所有cv限定符:

在所有情况下,typeid都会忽略cv-qualifiers(即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&&)";
Run Code Online (Sandbox Code Playgroud)

请注意,要比较2 typeid秒,您必须使用typeid(T).hash_code()或者std::type_index(typeid(T)),因为只有2个函数才能保证2个相同的typeids是相同的.例如,比较参考文献没有这种保证.

不能保证相同类型的typeid表达式的所有评估都会引用相同的std :: type_info实例,尽管那些type_info对象的std :: type_info :: hash_code将是相同的,就像它们的std: :type_index.

(参考文献)


正如@Yakk所提到的,你可以使用std::remove_referencestd::remove_cv获得你想要的行为.

std::remove_reference删除T的所有引用并std::remove_cv删除所有constvolatile限定符.你应该通过T,通过这些功能,他们传球之前std::is_same,这样std::is_same只比较的基础类型(如果有的话)的T1T2.

  • 他们的`operator ==`也保证对同类型描述符的'true`进行评估.所以你不能可靠地比较`&typeid(T)==&typeid(T)`,但是你可以*比较`typeid(T)== typeid(T)`并可靠地得到'true`. (4认同)