bar1
和bar2
的类型有什么区别?C++ 11自动声明带和不带指针声明者
int foo = 10;
auto bar1 = &foo;
auto *bar2 = &foo;
如果同时bar1
和bar2
是int*
,确实是有意义的写在bar2
声明指针声明符(*
)?
bar1
和bar2
的类型有什么区别?C++ 11自动声明带和不带指针声明者
int foo = 10;
auto bar1 = &foo;
auto *bar2 = &foo;
如果同时bar1
和bar2
是int*
,确实是有意义的写在bar2
声明指针声明符(*
)?
声明完全等价。 auto
工程(几乎)与template type deduction相同。明确地放置明星会使代码更容易阅读,并使程序员知道bar2
是一个指针。
就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 *
将演绎一个指向可变的,我们可以说const
明确地避免:
std::vector<X*> v = /* ... */;
for (const auto * p : v)
{
observe(p->foo()); // no need for a mutable *p
}
在这个具体的例子都bar1
和bar2
是相同的。这是一个个人喜好的问题,但我认为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;
}
使用auto *
“文件意图”。只有当expr
返回指针时,才能正确推导出auto *p = expr;
。例如:
int f();
auto q = f(); // OK
auto *p = f(); // error: unable to deduce 'auto*' from 'f()'
关于禁止非指针扣除的好处,upvoted。 – vsoftco
是的,但是下一个运算符&被重载以返回一个notnull或const传播的智能指针,然后auto *中断。 –
正如其他人所说,他们会生成相同的代码。星号是线路噪声(并且如果例如&foo
已被get_foo()
取代,则使得从原始指针切换到智能指针变得更难)。如果你想要明确,那么一定要明确;但是当你使用类型推断时,让编译器完成它的工作。缺少星号并不意味着对象不是指针。
我认为括号中的评论值得更加重视。即使在其他人提供的简单示例中,添加'*'可能会使代码更具可读性,但会增加维护难度。我个人认为'auto'的主要好处是便于维护,甚至比减少打字或提高可读性更重要。 – ToddR
有一个很大的区别,当你使用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
因为'MyFn'返回类型为'int','自动* P = FN(X,-X)'不会编译(这要归功于'*',否则我们应该等待'p-> Create()'出现错误):-)。 – Jarod42
@ Jarod42:是的,我使用的实体太少。固定。 –