相同的typeid名称但不是std::是否相同 使用C++(GCC 4.83.),我有2种类型( T1和 T2),具有奇怪的性质: Type ID(T1)、NAMEL()、/>代码>和 Type(T2)。 std::is_same::valueisfalse

相同的typeid名称但不是std::是否相同 使用C++(GCC 4.83.),我有2种类型( T1和 T2),具有奇怪的性质: Type ID(T1)、NAMEL()、/>代码>和 Type(T2)。 std::is_same::valueisfalse,c++,c++11,C++,C++11,这怎么可能?我如何进一步调查以确定原因?typeid忽略所有cv限定符: 在所有情况下,typeid都会忽略cv限定符(即typeid(T)=typeid(const T)) 这意味着typeid忽略所有引用&和const(仅举几例) inti=0; 常数int&&j=1; if(typeid(i).hash_code()==typeid(j).hash_code())//返回true std::cout忽略多态性,typeid()为您提供一个表示表达式静态类型的对象。但对于表达式类型,某些元

这怎么可能?我如何进一步调查以确定原因?

typeid
忽略所有cv限定符:

在所有情况下,typeid都会忽略cv限定符(即typeid(T)=typeid(const T))

这意味着
typeid
忽略所有引用
&
const
(仅举几例)

inti=0;
常数int&&j=1;
if(typeid(i).hash_code()==typeid(j).hash_code())//返回true

std::cout忽略多态性,
typeid()
为您提供一个表示表达式静态类型的对象。但对于表达式类型,某些元素会被忽略。从[expr]:

如果表达式最初具有类型“reference to
T
”(8.3.2,8.5.3),则在 任何进一步的分析。[…]如果prvalue最初的类型为“cv
T
”,其中
T
是cv非类、非数组类型,则 在进一步分析之前,将表达式调整为
T

因此,任何仅在顶级简历资格或参考方面不同的类型都将产生相同的typeid。例如,类型
int
const int
int&
volatile const int&
等都给您相同的
typeid()

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

typeid(T) == typeid(U) <==> std::is_same<T, U>
typeid(T)=typeid(U)std::是否相同
但正确的等价性是:

typeid(T) == typeid(U) <==> std::is_same<expr_type<T>, expr_type<U>>
typeid(T)=typeid(U)std::是否相同 其中:

template <class T>
using expr_type = std::remove_cv_t<std::remove_reference_t<T>>;
模板
使用expr\u type=std::remove\u cv\t;

typeid
忽略顶级限定符。^^这意味着像const和&@SergeyA这样的东西可能无法保证
typeid
将给您相同的
std::type_info
对象,但可以保证所有
std::type_info
对象都从
typeid(T)返回
对于相同的
T
比较相等。根据C++14 18.7.1/3,
std::type_info::operator==
如果两个操作数描述相同的类型,则返回
true
。@SergeyA:我认为这是对标准的恶意读取。[type.info]/1说“适合比较两种类型以获得相等”,我认为这几乎排除了总是返回
true
之类的愚蠢行为。为什么需要
hash\u code
进行比较?似乎更合理的做法是引入了
hash\u code
,以允许将typeid粘贴到无序的容器中。另外,不要将名称与typeid结果的值混淆。没有人声称名称具有所需的属性(当然,您也不会希望对名称进行散列)。它们的
运算符==
也保证对相同类型的描述符进行
true
计算。因此,您无法可靠地比较
&typeid(T)=&typeid(T)
,但您可以比较
typeid(T)=typeid(T)
,并可靠地得到
true
。提及
remove\u reference
remove\u cv
可能有助于OP解决其根本问题(而不仅仅是标题问题)。
template <class T>
using expr_type = std::remove_cv_t<std::remove_reference_t<T>>;