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

时间:2016-04-12 15:27:33

标签: c++ c++11

使用C ++(gcc 4.8.3)我有两种类型(T1T2),它们具有typeid(T1).name()typeid(T2).name()相同的奇怪属性但 std::is_same<T1, T2>::valuefalse

怎么会这样?我怎样才能进一步调查以说明原因可能是什么?

2 个答案:

答案 0 :(得分:14)

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

  

如果表达式最初具有类型“T的引用”(8.3.2,8.5.3),则类型将在T之前调整为T   进一步的分析。 [...]如果prvalue最初的类型为“ cv T”,其中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))

(ref)

这意味着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相同会是一样的。例如,比较参考文献没有这种保证。

  

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

(ref)

<小时/> 正如@Yakk所提到的,您可以使用std::remove_referencestd::remove_cv来获得您想要的行为。

std::remove_reference删除了T的所有引用,std::remove_cv删除了所有constvolatile限定符。您应该将T传递给这些函数,然后再将其传递给std::is_same,以便std::is_same仅比较T1T2的基础类型(如果有)。