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

时间:2016-01-01 21:45:03

标签: c++ c++11 auto variable-declaration

bar1bar2的类型之间有什么区别?

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

如果bar1bar2都是int*,那么在*声明中编写指针声明符(bar2)是否有意义?

6 个答案:

答案 0 :(得分:44)

使用auto *"记录意图"。只有auto *p = expr;返回指针时才能正确推导出expr。例如:

int f();

auto q = f(); // OK

auto *p = f(); // error: unable to deduce 'auto*' from 'f()'

答案 1 :(得分:40)

声明完全相同。 autotemplate type deduction(几乎)相同。明确地使用星形会使代码更容易阅读,并使程序员意识到bar2是一个指针。

答案 2 :(得分:14)

在此具体示例中,bar1bar2都相同。这是个人偏好的问题,但我会说bar2更容易阅读。

但是,这不适用于此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;
}

答案 3 :(得分:13)

使用{{1}}限定符时有很大差异:

{{1}}

答案 4 :(得分:10)

正如其他人所说,他们会生成相同的代码。星号是线路噪声(例如,如果&fooget_foo()替换,则会更难从原始指针切换到智能指针)。如果你想要明确,那么一定要明确;但是当你使用类型推断时,只需让编译器完成它的工作。缺少星号并不意味着物体不是指针。

答案 5 :(得分:6)

就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()

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

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