相同的类型名称,但不是标准::is_same
Same typeid name but not std::is_same
使用C++(gcc 4.8.3(我有2种类型(T1
和T2
(,它们具有奇怪的性质,即typeid(T1).name()
和typeid(T2).name()
是相同的,但是 std::is_same<T1, T2>::value
false
.
这怎么可能?我如何进一步调查以判断原因可能是什么?
忽略多态性,typeid()
为您提供一个表示表达式静态类型的对象。但是,当涉及到表达式类型时,某些元素会被忽略。从 [expr]:
如果表达式最初具有"对
T
的引用"类型(8.3.2,8.5.3(,则该类型将调整为T
任何进一步的分析。[...]如果 prvalue 最初具有类型"cvT
",其中T
是 cv 不合格的非类、非数组类型,则类型 在进行任何进一步分析之前,将表达式调整为T
。
因此,任何仅在顶级简历资格或参考方面不同的类型都将产生相同的类型ID。例如,int
、const int
、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>>;
typeid
忽略所有 cv 限定符:
在所有情况下,cv-限定符都被typeid忽略(即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 是相同的。例如,比较引用并不能保证。
不能保证同一类型上 typeid 表达式的所有计算都会引用相同的 std::type_info 实例,尽管这些type_info对象的 std::type_info::hash_code 是相同的,它们的 std::type_index 也是如此。
(参考资料(
如@Yakk所述,您可以使用
std::remove_reference
和std::remove_cv
来获得所需的行为。
std::remove_reference
删除 T 的所有引用,std::remove_cv
删除所有const
和volatile
限定符。在将这些函数传递给 std::is_same
之前,您应该通过这些函数传递T
,以便std::is_same
仅比较 T1
和 T2
的基础类型(如果有(。
- 使用CMake检测支持的C++标准
- 如何理解C++标准N3337中的expr.const.cast子句8
- "throw expression code" 1e7 >返回 d 是什么?投掷标准::overflow_error( "too big" ) : d;意味 着?
- 编译标准库类型
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- Why is UINT32_MAX + 1 = 0?
- C++错误:"error: int aaa::bbb is protected within this context"
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 铸造标准::有没有回到原来的类型
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 标准 N3337 5.2.10 第 7 条中的C++"类型"是什么意思?
- this_thread::sleep_for和计时时钟之间的关系是否由C++11标准指定
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- 标准库类型的赋值运算符的引用限定符
- 标准是否严格定义了该程序应该如何编译?
- 如何从Windows应用程序输出到标准?
- 安全到标准:移动会员?
- 如何正确将字符串转换为标准::时间::system_clock::time_point?
- 这是否符合C++标准:双响双响,例如!!(-0.0).
- C++11标准是否保证"auto n2 = const_cast<int&>(n);" "n2 is int&"?