C ++ auto& vs汽车

时间:2015-04-25 00:58:25

标签: c++ auto

创建局部变量时,使用(const) auto&auto

是否正确

e.g:

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

const auto& result = object.SomeMethod();

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

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

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

for(const auto& object : objects)

4 个答案:

答案 0 :(得分:56)

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

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

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

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

auto &auto const &更具体一点:

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

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

  

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

没有区别。

  

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

是。应用上述原则,

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

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

答案 1 :(得分:30)

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

使用auto的一般规则是:

  • 如果要处理副本,请选择auto x
  • 如果您要使用原始项目,请选择auto &x,然后修改它们。
  • 如果您想使用原始项目,请选择auto const &x 不要修改它们。

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

答案 2 :(得分:6)

auto使用相同的类型推导机制作为模板,我所知道的唯一例外是由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是左值参考,其cv限定符为expression。如果expression是右值,则x是右值参考。

答案 3 :(得分:1)

  

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

是。 auto只不过是编译器推导的类型,因此请使用通常使用引用的引用,以及通常使用本地副本的本地(自动)副本。是否使用引用与类型扣除无关。

  

SomeMethod()返回非原始值 - 可能是另一个用户定义的类型。我的理解是const auto&结果是正确的,因为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-by-value-optimization

  

原始类型怎么样?我假设const auto sum = 1 + 2;是对的。

是的,这很好。

  

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

     

for(const auto& object:objects)

是的,这也没关系。我一直都在写这种代码。