C++ 自动*的类型扣除规则是什么?

C++ 自动*的类型扣除规则是什么?,c++,templates,auto,decltype,type-deduction,C++,Templates,Auto,Decltype,Type Deduction,auto*的类型扣除规则是什么 考虑以下几点: int x = 64; int* px = &x; auto* v1 = &x; // auto => ??? ok v1 is int* ... auto* v2 = px; // auto => ??? is v2 int* ? auto* v3 = &px; // auto => ??? is v3 int** ? 为了澄清我的问题,如果我们将类型推断分为两个步

auto*
的类型扣除规则是什么

考虑以下几点:

int x = 64;
int* px = &x;

auto* v1 = &x;    // auto => ???    ok v1 is int* ...
auto* v2 = px;    // auto => ???    is v2 int*  ?
auto* v3 = &px;   // auto => ???    is v3 int** ?
为了澄清我的问题,如果我们将类型推断分为两个步骤:

  • 在没有(
    *
    )的情况下推断“
    auto
    ”本身的类型。。。然后
  • 在添加(
    *
    )之后推断对象的类型(
    v1
    v2
    v3
  • 所以我的两个问题是:

  • 如果没有(
    *
    ),自动
    将被推断为什么
  • v2
    是指向
    int
    int*
    )的指针还是指向指针(
    int**
    )的指针

  • auto
    将推导出给定表达式的cv限定类型
    auto*
    将推导出表达式指向的cv限定类型(如果表达式是指针),否则将无法编译

    对于给定的示例,
    v
    的实际类型将是指向int的
    指针,与
    v2
    相同,而对于
    v3
    则是指向int的
    指针


    如果您的第一个示例编写为
    auto v1=&px
    ,则v1的类型将保持不变。

    演绎过程与模板参数相同。如果我这样做:

    int a = 0;
    auto* b = &a;
    
    b
    的类型将是
    int*
    。和写作:

    auto b = &a;
    
    将产生相同的类型,
    int*

    在您的示例中,编译器将以某种方式添加缺少的星号。但是最简单的形式是只写
    auto
    ,您可以使用
    typeid
    来回答您的问题

    #include <iostream>
    #include <typeinfo>
    using namespace std;
    
    int main() {
        // your code goes here
        int x = 64;
        int* px = &x;
    
        auto* v1 = &x;   
        auto* v2 = px;    
        auto* v3 = &px;   
        cout<<typeid(v1).name()<<endl;
        cout<<typeid(v2).name()<<endl;
        cout<<typeid(v3).name()<<endl;
        return 0;
    }
    
    Pi-->指向整数变量的指针

    PPi-->指向整数变量指针的指针

    如果您知道模板类型推断,您将知道几乎所有的
    自动
    类型推断。因为自动类型推断与模板类型推断类似

    使用
    auto
    声明变量时,
    auto
    在模板中充当
    T
    ,类型说明符充当参数类型:

    将转化为:

    template<typename T>
    void func(const T param) { ... }
    //        ^^^^^^^
    
    翻译为:

    template<typename T>
    void func(const T& param) 
    //        ^^^^^^^^
    
    变成

    template<typename T>
    void func(T* param)
    
    由于您正在获取指针的地址,因此变为
    int**

    template<typename T>
    void func(T** param)
    //        ^^^
    
    哪些产出:

    int*
    int*
    int**
    

    自动类型推断和模板类型推断之间有一个重要区别,即
    std::initializer\u list

    考虑以下例子:

    auto i = 1;   // int
    auto j(1);    // int
    auto k = { 1 }// std::initializer_list<int> !
    auto l { 1 }  // std::initializer_list<int> !
    

    Clang 3.8中已经实现了一些功能,可以将直接列表初始化与auto一起使用(即将推出的标准)

    我知道auto的工作原理与template完全相同。。。事实上,我了解大多数关于自动和模板的类型推导,但让我困惑的是(自动*),如果我想扩展我的问题,我也会从模板中询问(T*):)。。。不幸的是,我没有boost库:(但是+1…谢谢
    template<typename T>
    void func(T* param)
    
    auto* v3 = &px;
    
    template<typename T>
    void func(T** param)
    //        ^^^
    
    #include <iostream>
    #include <boost/type_index.hpp>
    using namespace std;
    using namespace boost::typeindex;
    
    int main()
    {
        int x = 64;
        int* px = &x;
    
        auto* v1 = &x;
        auto* v2 = px;
        auto* v3 = &px;
        cout << type_id_with_cvr<decltype(v1)>().pretty_name() << '\n';
        cout << type_id_with_cvr<decltype(v2)>().pretty_name() << '\n';
        cout << type_id_with_cvr<decltype(v3)>().pretty_name() << '\n';
    }
    
    int*
    int*
    int**
    
    auto i = 1;   // int
    auto j(1);    // int
    auto k = { 1 }// std::initializer_list<int> !
    auto l { 1 }  // std::initializer_list<int> !
    
    auto i = int{ 1 }; // type is int