C++ 这两种类型是同一类型的吗?

C++ 这两种类型是同一类型的吗?,c++,c++11,templates,decltype,typeid,C++,C++11,Templates,Decltype,Typeid,我对我编写的这个模板感到非常困惑,它应该“自动”推断我传入的指针类型,但编译器似乎不认为这两种类型是相同的,而我却认为是相同的,typeid()站在我这边 #include <iostream> template <auto* static_ptr_to_object> struct Handle { // static_ptr_to_object should be a pointer to a Whale<char> // Both of

我对我编写的这个模板感到非常困惑,它应该“自动”推断我传入的指针类型,但编译器似乎不认为这两种类型是相同的,而我却认为是相同的,
typeid()
站在我这边

#include <iostream>

template <auto* static_ptr_to_object>
struct Handle
{
    // static_ptr_to_object should be a pointer to a Whale<char>
    // Both of the following typedefs should result in types of Whale<char>
    // When I cout typeid() of these types it prints out the same types
    // However std::is_same_v returns false

    using pointee_type1 = std::remove_pointer_t<decltype(static_ptr_to_object)>;
    using pointee_type2 = decltype(*static_ptr_to_object); // The two are the same types

    void showTypes()
    {
        //static_assert(std::is_same_v<pointee_type1, pointee_type2>);
        // Uncommenting this line will make the static assert fail

        std::cout << "Type of 'pointee_type1' = " << typeid(pointee_type1).name() << "\n";
        std::cout << "Type of 'pointee_type2' = " << typeid(pointee_type2).name() << "\n";

        if (typeid(pointee_type1) == typeid(pointee_type2))
            std::cout << "Types are the same\n";
        else std::cout << "Types are not the same\n";

    }

    bool b1 = std::is_integral_v<decltype(pointee_type1::member)>;
    // Uncommenting the below line will make compilation fail

    //bool b2 = std::is_integral_v<decltype(pointee_type2::member)>;
    // pointee_type2 must be a class or namespace when followed by ::
    // pointee_type2 left of '::' must be a class or namespace name
    

};

template <typename T>
struct Whale
{
    T member;
};

Whale<char> whale;

int main()
{
    Handle<&whale> handleToWhale;
    handleToWhale.showTypes();
}
#包括
在某些情况下,指针取消引用将如何返回引用类型的模板。

  • 如果参数是一个未加密的id表达式或一个未加密的类成员访问表达式,则decltype将生成由该表达式命名的实体的类型

  • 如果参数是T类型的任何其他表达式,并且

    a) …
    b) 如果表达式的值类别为左值,则decltype产生T&
    c)

  • *static_ptr_to_object
    适合第二种情况,它是一个左值表达式,因此
    decltype(*static_ptr_to_object)
    生成一个引用类型,即
    Whale&
    pointee_type1
    pointee_type2
    不是同一类型

    您可以使用
    std::remove_reference
    获得与以下相同的类型:

    using pointee_type2 = std::remove_reference_t<decltype(*static_ptr_to_object)>;
    
    使用pointee_type2=std::remove_reference\t;
    
    另一方面,确实会产生相同的结果(相同的
    std::type_info
    object)

    如果type是引用类型,则结果引用表示引用类型的std::type_info对象


    pointee_type1
    Whale
    ,但是
    pointee_type2
    Whale&
    。删除引用,这样您就可以得到相同的名称。

    关于
    名称的有趣事实:。因此,这不是模板的事情,取消引用指针会为您提供指向它所指向的任何对象的引用,任何被取消引用的指针的decltype都将引用指向的任何类型?@Zebrafish
    decltype
    以两种不同的方式工作。对于id表达式,它生成由id表达式命名的实体的确切类型。对于其他表达式,它不仅根据表达式的类型给出结果,还根据表达式的值类别给出结果。若指针上的解引用导致左值表达式,那个么您将得到
    T&