带有和不带有指针声明符的C++11自动声明
C++11 auto declaration with and without pointer declarator
bar1
和bar2
的类型有什么区别?
int foo = 10;
auto bar1 = &foo;
auto *bar2 = &foo;
如果bar1
和bar2
都是int*
,那么在bar2
声明中写入指针声明符(*
)有意义吗?
声明完全等效。auto
的工作原理(几乎)与模板类型推导相同。明确地放置星号使代码更容易阅读,并使程序员意识到bar2
是一个指针。
使用auto *
"文档意图"。只有当expr
返回指针时,才能正确推导出auto *p = expr;
。示例:
int f();
auto q = f(); // OK
auto *p = f(); // error: unable to deduce 'auto*' from 'f()'
使用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
在这个特定的例子中,bar1
和bar2
是相同的。这是个人偏好的问题,尽管我认为bar2
更容易阅读。
然而,这并不适用于本例中的参考文献:
#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;
}
正如其他人所说,他们将生成相同的代码。星号是行噪声(例如,如果&foo
被get_foo()
取代,则会使从原始指针切换到智能指针变得更加困难)。如果你想明确,那么无论如何,都要明确;但是,当您使用类型推断时,只需让编译器完成它的工作即可。缺少星号并不意味着对象不是指针。
对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的正确性。考虑下一个例子,其中容器包含指向可变的指针,但我们只需要常量访问。仅仅auto *
就可以推导出一个指向可变的指针,我们可以通过显式地说const
来避免这种情况:
std::vector<X*> v = /* ... */;
for (const auto * p : v)
{
observe(p->foo()); // no need for a mutable *p
}
- 使用 (c++11) 声明类型时放置 __declspec(dllimport) 关键字的位置
- C++ 11 通过在类声明中使用指针来节省内存
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- 如何实现声明功能-C 11,编译时间
- 如何使用 c++11 函数回调声明多个模板参数
- C++11: "decltype(1+2)"声明 xvalue 还是 prvalue?
- 不能和正确的方法来声明类成员 c++11 中的 int 数组数组
- 为什么即使在启用 C++11 并且我包含字符串之后,'stod'仍然没有在此范围内声明?
- 为什么 C++11 允许您将局部变量声明为 thread_local
- C++11 外部作用域变量声明为 auto
- 无法在 c++ 中声明动态整数数组,可能是 c++11 错误
- C++11 - 如何在C++11中做出此Qt声明
- 静态成员声明 c++11
- 使用新的 C++11 语法的 auto 进行函数声明,但使用 auto&并且没有 ->
- 标记C 声明的一种便携式方式,为C 11所接受的弃用
- 声明中的循环依赖性C 11
- 使用 C++11 auto 关键字声明两个(或多个)变量
- 可以在C 11中有条件声明的朋友类
- 有没有办法在声明中缩短C 11 lambda签名
- C++11:模板专用化的 constexpr 成员的标准参考需要额外声明