C++ 汽车与汽车

C++ auto& vs auto

本文关键字:汽车 C++      更新时间:2023-10-16

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

例如:

SomeClass object;
const auto result = object.SomeMethod();

const auto& result = object.SomeMethod();

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

对于基元类型呢?我认为const auto sum = 1 + 2;是正确的。

这也适用于基于范围的for循环吗?

for(const auto& object : objects)

autoauto &&涵盖了大多数情况:

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

  • 如果不关心对象是否为本地对象,请使用auto &&。从技术上讲,这总是会产生一个引用,但如果初始值设定项是临时的(例如,函数按值返回),它的行为本质上就像你自己的本地对象。

    此外,auto &&也不能保证对象是可修改的。给定一个const对象或引用,它将推导出const。然而,在特定的上下文中,通常假设可修改性。

auto &auto const &的特异性稍高:

  • auto &保证您正在与其他对象共享该变量。它总是一个参考,而不是一个临时的。

  • auto const &类似于auto &&,但提供只读访问。

基元/非基元类型如何?

没有区别。

这也适用于基于范围的for循环吗?

是。应用上述原理,

  • 使用auto &&可以修改和丢弃循环中序列的值。(也就是说,除非容器提供只读视图,例如std::initializer_list,否则在这种情况下,它实际上是一个auto const &。)
  • 使用auto &以有意义的方式修改序列的值
  • 使用auto const &进行只读访问
  • 使用auto处理(可修改的)副本

您还提到了auto const,但没有提及。这是有效的,但它不是很常用,因为对您已经拥有的东西进行只读访问很少有优势。

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

使用auto的一般规则是:

  • 如果要使用副本,请选择auto x
  • 如果要使用原始项目并可能对其进行修改,请选择auto &x
  • 当您想要处理原始项目时,选择auto const &x而不是修改它们

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

auto使用与模板相同的类型推导机制,我所知道的唯一例外是大括号init列表,它由auto推导为std::initializer_list,但在模板上下文中不推导。

auto x = expression;

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

另一种形式,

auto& x = expression

不会剥离cv限定符,因此,使用上面的示例,auto& x = f()x推断为const int&。其他组合只是添加了cv限定符。

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

因此,简而言之,如果您想要副本,请使用auto;如果您想要引用,请使用auto&。只要需要额外的const度,请使用const


编辑还有一个额外的用例,

auto&& x = expression;

其使用与在模板代码中转发引用的情况相同的引用折叠规则。如果expression是左值,则x是具有expression的cv限定符的左值引用。如果expression是右值,那么x是右值引用。

在创建局部变量时,使用(const)auto&还是汽车?

是。auto只不过是编译器推导的类型,所以在通常使用引用的地方使用引用,在通常使用本地副本的地方使用本地(自动)副本。是否使用引用与类型推导无关。

其中SomeMethod()返回一个非基元值-可能是另一个用户定义的类型。我的理解是constauto&结果是正确的,因为SomeMethod()返回的结果将调用返回类型的复制构造函数。如果我错了,请纠正我。

是否合法?是的,带着const。最佳实践?可能不会。至少,C++11不会。特别是如果从SomeMethod()返回的值已经是临时的,则不会。您将希望了解C++11移动语义、复制省略和返回值优化:https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by-value/

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=199

https://isocpp.org/wiki/faq/ctors#return-按价值优化

对于基元类型呢?我假设const auto-sum=1+2;是正确的。

是的,这很好。

这也适用于基于范围的for循环吗?

对于(const-auto&object:objects)

是的,这也可以。我一直在工作中编写这种代码。