代码之家  ›  专栏  ›  技术社区  ›  Henry Barker

带和不带指针声明符的C++11自动声明

  •  61
  • Henry Barker  · 技术社区  · 9 年前

    不同类型的 bar1 bar2 ?

    int foo = 10;
    auto bar1 = &foo;
    auto *bar2 = &foo;
    

    如果两者都 巴1 巴2 int* ,编写指针声明符有意义吗( * )在 巴2 公告

    6 回复  |  直到 9 年前
        1
  •  59
  •   vsoftco    9 年前

    声明完全相同。 auto 工作原理(几乎)与 template type deduction 。显式地加上星号使代码更容易阅读,并使程序员意识到 bar2 是指针。

        2
  •  58
  •   Victor Dyachenko    9 年前

    使用 auto * “文件意图”。和 auto *p = expr; 只有当 expr 返回指针。例子:

    int f();
    
    auto q = f(); // OK
    
    auto *p = f(); // error: unable to deduce 'auto*' from 'f()'
    
        3
  •  23
  •   danpla    8 年前

    当你使用 const 限定符:

    int i;
    
    // Const pointer to non-const int
    const auto ip1 = &i; // int *const
    ++ip1; // error
    *ip1 = 1; // OK
    
    // Non-const pointer to const int
    const auto* ip2 = &i; // int const*
    ++ip2; // OK
    *ip2 = 1; // error
    
        4
  •  17
  •   Hatted Rooster    9 年前

    在此特定示例中 bar1 bar2 都是一样的。这是个人偏好的问题,尽管我会这么说 巴2 更容易阅读。

    然而,如本文所示,这并不适用于参考文献 example :

    #include <iostream>
    using namespace std;
    
    int main() {
        int k = 10;
        int& foo = k;
        auto bar = foo; //value of foo is copied and loses reference qualifier!
        bar = 5; //foo / k won't be 5
        cout << "bar : " << bar << " foo : " << foo << " k : " << k << endl;
        auto& ref = foo;
        ref = 5; // foo / k will be 5
        cout << "bar : " << bar << " foo : " << foo << " k : " << k;
        return 0;
    }
    
        5
  •  12
  •   Jeff Schwab    9 年前

    正如其他人所说,它们将生成相同的代码。星号是线噪声(如果例如, &foo 被替换为 get_foo() ). 如果你想明确,那么无论如何,都要明确;但是当您使用类型推断时,只需让编译器完成它的工作。缺少星号并不意味着对象不是指针。

        6
  •  9
  •   Kerrek SB    9 年前

    这与C++代码的解释无关;你想写什么就写什么。然而,还有一个风格和可读性的问题:通常,你不应该在类型别名中隐藏指针、引用和CV限定符,甚至可能是智能指针,因为这会让读者更难理解这是怎么回事。类型别名应该封装语义相关的类型内容,而限定符和修饰符应该保持可见。因此,更喜欢以下内容:

     using Foo = long_namespace::Foobrigation<other_namespace::Thing>;
     using MyFn = const X * (int, int);
    
     std::unique_ptr<Foo> MakeThatThing(MyFn & fn, int x)   // or "MyFn * fn"
     { 
         const auto * p = fn(x, -x);
         return p ? p->Create() : nullptr;
     }
    

    不要说:

    using PFoo = std::unique_ptr<Foo>;   // just spell it out
    using MyFn = int(&)(int, int);       // unnecessary; & is easy to spell
    auto p = fn(x, -x);                  // Don't know that p is a pointer
    

    还请注意,引用限定符(与指针不同)确实会更改所声明的变量的类型,因此它们不是可选的:

    X & f();
    auto a = f();    // copy!
    auto & b = f();  // b is the same as the return value of f()
    

    最后,添加显式常量指针限定可以帮助常量正确性。考虑下一个示例,其中容器包含指向可变的指针,但我们只需要常量访问。只是 auto * 将推导出指向可变的指针,我们可以通过以下语句来避免 const 明确地:

    std::vector<X*> v = /* ... */;
    for (const auto * p : v)
    {
        observe(p->foo());   // no need for a mutable *p
    }