V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
codechaser
V2EX  ›  C

C++中`auto`这个关键字的一点疑惑。

  •  
  •   codechaser · 2018-11-29 16:50:36 +08:00 · 3025 次点击
    这是一个创建于 1946 天前的主题,其中的信息可能已经有所发展或是发生改变。
    int foo = 11;
    const int &a = 10;
    int *p = &foo;
    
    auto x = foo;
    auto y = a;
    auto &yy = a;
    auto pp = p;
    auto *ppp = p;
    
    cout << y << endl;
    cout << yy << endl;
    cout << pp << endl;
    cout << ppp << endl;
    

    输出:

    10
    10
    0x61fefc
    0x61fefc
    

    这段程序的前面我都理解,到了pp这里我就有点疑惑了,C++ Primer 上说auto会推断出基本数据类型,那么按理说*这种指针声明也应该去掉了,所以auto *ppp = p;才是正确的吧?但是auto pp = p;与这一句输出了指针的值相同的结果,这是为什么呢?在网上找了一下,发现没有什么太好的解释,求教。

    18 条回复    2018-11-30 09:45:09 +08:00
    codehz
        1
    codehz  
       2018-11-29 16:59:35 +08:00
    codehz
        2
    codehz  
       2018-11-29 17:01:27 +08:00
    基本上就是和 decay 表现一致,可以看这个
    codechaser
        3
    codechaser  
    OP
       2018-11-29 17:06:29 +08:00
    @codehz 看了一下,意思是说会隐式转换吗?我刚接触 C++,这个文档看的云里雾里的。😂
    after1990s
        4
    after1990s  
       2018-11-29 17:25:54 +08:00
    auto 的类型推导和模板是基本一致的。

    对于刚入门的来说,这个话题有点过难了。
    codehz
        5
    codehz  
       2018-11-29 17:26:27 +08:00
    auto 的类型 deduce 规则和 decay 的结果是一致的,其实就是一种类型的退化,把 cv 限定符 /引用 /不规范的函数类型干掉了。。(标准是 10.1.7.4.1 Placeholder type deduction [dcl.type.auto.deduct] 写的比较混乱,我个人总结就是把 auto 当作 std::decay_t<decltype(rhs)>这样去理解。。。
    Yvette
        6
    Yvette  
       2018-11-29 17:30:26 +08:00 via iPhone   ❤️ 1
    首先明确 auto 的 * 是声明符的一部分,不是 base type 的一部分。

    这样理解吧,因为 p 的 type 是 int *,base type 为 int,所以 auto deduce 出来 pp 为 int * 是合理的。而 ppp 声明中 * 是作用于 auto,用来明确 p 必须为 pointer,否则报错;如果不加 * (如 pp 这种情况)则如果 p 不是 pointer 也不会报错。
    Yvette
        7
    Yvette  
       2018-11-29 17:43:22 +08:00 via iPhone
    总的来说就是 auto 后面 * 的作用是为了确保赋值符右边为 pointer 而不是为了声明新的变量为 pointer,虽然效果一样。而 auto 本身的作用是用赋值符右边的 type (不是 base type ) deduce 出新变量的 type。把声明 pp 和 ppp 中的 p 换成一个 int (比如 foo )跑一遍看看报错可能容易理解一些。
    codechaser
        8
    codechaser  
    OP
       2018-11-29 17:45:16 +08:00
    @Yvette `base type 为 int,所以 auto deduce 出来 pp 为 int * 是合理的。`既然是 int 的,那么 pp 为 int *为什么就合理了呢?
    Yvette
        9
    Yvette  
       2018-11-29 17:53:30 +08:00 via iPhone   ❤️ 1
    @codechaser 因为 p 的 type 是 int *

    auto 的结果与 base type 无关,而是与 type 有关,提了句 base type 是为了稍微纠正一下
    Yvette
        10
    Yvette  
       2018-11-29 17:59:28 +08:00 via iPhone
    @codechaser 简单来说就是两点:
    1. auto 的结果为忽略了 top-level const 的 type
    2. auto 的 type modifier 是为了确保右边返回的 type,而不是为了隐式转换
    codechaser
        11
    codechaser  
    OP
       2018-11-29 18:58:38 +08:00
    @Yvette 谢谢!
    Akiyu
        12
    Akiyu  
       2018-11-29 19:22:15 +08:00
    上面那位 dalao 说得我都晕了
    本着 less is more 的原则, 你这么简单记一下:
    auto 会去除顶层 const 和引用属性

    @btw: 如果你拿不准的话 decltype 可以推断出完整的属性

    (如果我没弄错的话)
    turi
        13
    turi  
       2018-11-29 19:49:20 +08:00
    Effective Modern C++ 里面讲解的很清楚,基本上就是 4 楼的意思
    codechaser
        14
    codechaser  
    OP
       2018-11-29 20:09:12 +08:00
    @Akiyu auto 是会去除顶层 const 和引用属性,可是我不解的是 pp 和 ppp 都被推断成了 int *类型。
    codehz
        15
    codehz  
       2018-11-30 05:34:57 +08:00
    原来你问这个啊,这样的话你可以把 auto 理解为类型占位符,和方程里的未知数一个意思,事实上文档里就是这么写的。。。
    aijam
        16
    aijam  
       2018-11-30 07:29:33 +08:00
    感觉 lz 对指针写在等号左边和右边的语义不同不太熟悉。
    对于等号右边的指针 p 来说,p 的类型是 int*, *p 的类型是一个 int。
    当你写 auto pp = p,auto 推断出 pp 和 p 一样都是 int*,此时 pp == p == 0x61fefc
    当你写 auto pp = *p, auto 推断出 pp 和*p 一样都是 int,此时 pp == *p == 11
    逻辑很自然啊。
    aijam
        17
    aijam  
       2018-11-30 07:38:03 +08:00
    同理,auto *ppp 声明了 ppp 是一个指针,但我们不知道这个指针指向的类型是什么,需要 auto 来推导 ppp 是什么类型的指针。那么当你写 auto *ppp = p,说明 ppp 和 p 一样都是 int*。
    codechaser
        18
    codechaser  
    OP
       2018-11-30 09:45:09 +08:00
    @aijam 这样的啊?谢谢啊!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   982 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 21:57 · PVG 05:57 · LAX 14:57 · JFK 17:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.