type_info没有考虑简历限定符:这是对的吗?

type_info doesn't account for cv qualifiers: is this right?

本文关键字:info type      更新时间:2023-10-16

这段代码打印1是正确的行为还是g++4.5的一个怪癖?

#include <iostream>
#include <typeinfo>
using namespace std;
int main(){
    struct A{};
    cout<<(typeid(A)==typeid(const A)&&typeid(A)==typeid(const volatile A)&&typeid(A)==typeid(volatile A));
}

我认为cv限定符不同的类型被视为非常不同的类型,即使较少的cv限定类型可以隐式转换为较多的cv限制类型。

typeid根据C++标准(取自ISO/IEC 14882:2003的§5.2.8)忽略cv限定符:

左值表达式的顶级cv限定符或typeid的操作数类型id总是已忽略。[示例:

class D { ... };
D d1;
const D d2;
typeid(d1) == typeid(d2);       // yields true
typeid(D) == typeid(const D);   // yields true
typeid(D) == typeid(d2);        // yields true
typeid(D) == typeid(const D&);  // yields true

--结束示例]

所以,你看到的结果是意料之中的。

正如@SanderDicker提到的cv限定符被忽略。但不是指针!

示例:

#include <iostream>
#include <typeinfo>
int main()
{
    int bar = 1;
    const int cbar = 10;
    volatile int vbar = 10;
    const volatile int cvbar = 1000;
    int &rbar = bar;
    const int &crbar = bar;
    volatile int &vrbar = bar;
    const volatile int &cvrbar = bar;
    int *pbar = &bar;
    const int *cpbar = &bar;
    volatile int *vpbar = &bar;
    const volatile int *cvpbar = &bar;
    const volatile int * const cvpcbar = &bar;
    const volatile int * const volatile cvpcvbar = &bar;
    int&& rrbar = 894354;
    const int&& rrcbar = 894354;
    std::cout << typeid(bar).name() << 'n';
    std::cout << typeid(cbar).name() << 'n';
    std::cout << typeid(vbar).name() << 'n';
    std::cout << typeid(cvbar).name() << 'n';
    std::cout << typeid(rbar).name() << 'n';
    std::cout << typeid(crbar).name() << 'n';
    std::cout << typeid(vrbar).name() << 'n';
    std::cout << typeid(cvrbar).name() << 'n';
    std::cout << typeid(pbar).name() << 'n';
    std::cout << typeid(cpbar).name() << 'n';
    std::cout << typeid(vpbar).name() << 'n';
    std::cout << typeid(cvpbar).name() << 'n';
    std::cout << typeid(cvpcbar).name() << 'n';
    std::cout << typeid(cvpcvbar).name() << 'n';
    std::cout << typeid(rrbar).name() << 'n';
    std::cout << typeid(rrcbar).name() << 'n';
    std::cout << "nn";
}

输出

int
int
int
int
int
int
int
int
int * __ptr64
int const * __ptr64
int volatile * __ptr64
int const volatile * __ptr64
int const volatile * __ptr64
int const volatile * __ptr64
int
int

正如您所看到的,在涉及指针的5种情况下,cv限定符并没有被忽略。MSVS或g++和C++11、C++14、C++17的输出相同。