相同的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 toT
”(8.3.2,8.5.3),则在
任何进一步的分析。[…]如果prvalue最初的类型为“cvT
”,其中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>>;