C++ auto&vs auto

roh*_*unb 58 c++ auto

创建局部变量时,使用(const) auto&或是正确的auto吗?

例如:

SomeClass object;
const auto result = object.SomeMethod();
Run Code Online (Sandbox Code Playgroud)

要么 const auto& result = object.SomeMethod();

SomeMethod()返回非原始值 - 可能是另一个用户定义的类型.我的理解是const auto& result正确的,因为SomeMethod()返回的结果将为返回的类型调用复制构造函数.如果我错了,请纠正我.

原始类型怎么样?我认为const auto sum = 1 + 2;是正确的.

这是否也适用于基于范围的循环?

for(const auto& object : objects)
Run Code Online (Sandbox Code Playgroud)

Pot*_*ter 71

autoauto &&涵盖大多数情况:

  • 使用auto时,你需要一个本地副本.这永远不会产生参考.复制(或移动)构造函数必须存在,但由于复制省略优化,它可能不会被调用.

  • auto &&当您不关心对象是否是本地对象时使用.从技术上讲,这将始终生成一个引用,但如果初始化程序是临时的(例如,函数按值返回),它的行为基本上就像您自己的本地对象.

    此外,auto &&也不保证对象可以修改.给定一个const对象或引用,它将推断出来const.但是,考虑到具体情况,通常会假设可修改性.

auto &并且auto const &更具体一点:

  • auto &保证您与其他人共享变量.它始终是一个参考,永远不会是一个临时的.

  • auto const &就像auto &&,但提供只读访问权限.

原始/非原始类型怎么样?

没有区别.

这是否也适用于基于范围的循环?

是.应用上述原则,

  • 使用auto &&了修改,并丢弃循环中的序列值的能力.(也就是说,除非容器提供只读视图,例如std::initializer_list,在这种情况下它将是有效的auto const &.)
  • 用于auto &以有意义的方式修改序列的值.
  • 使用auto const &的只读访问.
  • 使用auto与(修改)拷贝工作.

你也提到auto const没有参考.这是有效的,但它并不常用,因为对您已经拥有的东西进行只读访问很少有优势.

  • 从本质上讲,“auto&”似乎是一个不错的选择。但是当你想添加尚不存在的常量时,请使用“const auto&”。`auto&&` 用于转发,我确实认为这种情况发生的频率比 Sutter 想象的要高。例如,您可能希望通过“auto&&”存储返回值,然后将其“转发”到两个事物,例如 std::cout 以查看用于调试的值并将其传递给其他函数。我以前经常使用 auto&&,但当它做了一些意想不到的事情时,我就被它咬过一两次。我希望我能更加注意出了什么问题! (2认同)

pha*_*tom 33

是的,使用autoauto&局部变量是正确的.获取函数的返回类型时,使用也是正确的auto&.这也适用于基于范围的循环.

使用的一般规则auto是:

  • 选择auto x何时使用副本.
  • 选择auto &x何时使用原始项目并可以修改它们.
  • 选择auto const &x何时使用原始项目,不会修改它们.

您可以在此处阅读有关自动说明符的更多信息.


vso*_*tco 7

auto使用相同的类型推导机制作为模板,我知道的唯一例外是brace-init列表,它是由autoas 推导出来的std::initializer_list,但在模板上下文中是非推导的.

auto x = expression;
Run Code Online (Sandbox Code Playgroud)

首先从右侧表达式的类型中剥离所有引用和cv限定符,然后匹配类型.例如,如果你有,const int& f(){...}那么auto x = f();推断xint,而不是 const int&.

另一种形式,

auto& x = expression
Run Code Online (Sandbox Code Playgroud)

不会剥离 cv限定符,因此,使用上面的示例,auto& x = f()推导xconst int&.其他组合只添加cv限定符.

如果您希望始终使用cv-ref限定符推导出您的类型,请使用decltype(auto)C++ 14中的臭名昭着,它使用decltype类型推导规则.

因此,简而言之,如果您想要副本,请使用auto,如果您想要参考,请使用auto&.const随时随地使用const.


编辑 还有一个用例,

auto&& x = expression;
Run Code Online (Sandbox Code Playgroud)

它使用引用 - 折叠规则,与模板代码中转发引用的情况相同.如果expression是左值,则x是具有cv限定符的左值引用expression.如果expression是右值,则x是右值参考.