C++ 自动& vs 自动

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29859796/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 21:14:37  来源:igfitidea点击:

C++ auto& vs auto

c++auto

提问by rohunb

When creating local variables, is it correct to use (const) auto&or auto?

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

e.g.:

例如:

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

or const auto& result = object.SomeMethod();

或者 const auto& result = object.SomeMethod();

Where SomeMethod() returns a non-primitive value - maybe another user-defined type. My understanding is that const auto& resultis correct since the result returned by SomeMethod() would call the copy constructor for the returned type. Please correct me if I am wrong.

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

What about for primitive types? I assume const auto sum = 1 + 2;is correct.

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

Does this also apply to range based for loops?

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

for(const auto& object : objects)

回答by Potatoswatter

autoand auto &&cover most of the cases:

autoauto &&涵盖大多数情况:

  • Use autowhen you need a local copy. This will never produce a reference. The copy (or move) constructor must exist, but it might not get called, due to the copy elisionoptimization.

  • Use auto &&when you don't care if the object is local or not. Technically, this will always produce a reference, but if the initializer is a temporary (e.g., the function returns by value), it will behave essentially like your own local object.

    Also, auto &&doesn't guarantee that the object will be modifiable, either. Given a constobject or reference, it will deduce const. However, modifiability is often assumed, given the specific context.

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

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

    此外,auto &&也不保证该对象是可修改的。给定一个const对象或引用,它会推导出const。但是,鉴于特定的上下文,通常会假设可修改性。

auto &and auto const &are a little more specific:

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

  • auto &guarantees that you are sharing the variable with something else. It is always a reference and never to a temporary.

  • auto const &is like auto &&, but provides read-only access.

  • auto &保证您正在与其他东西共享变量。它始终是一个参考,而不是临时的。

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

What about for primitive/non-primitive types?

对于原始/非原始类型呢?

There is no difference.

没有区别。

Does this also apply to range based for loops?

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

Yes. Applying the above principles,

是的。运用以上原则,

  • Use auto &&for the ability to modify and discard values of the sequence within the loop. (That is, unless the container provides a read-only view, such as std::initializer_list, in which case it will be effectively an auto const &.)
  • Use auto &to modify the values of the sequence in a meaningful way.
  • Use auto const &for read-only access.
  • Use autoto work with (modifiable) copies.
  • 使用auto &&了修改能力和内环路的序列丢弃值。(也就是说,除非容器提供只读视图,例如std::initializer_list,在这种情况下,它实际上是一个auto const &。)
  • 用于auto &以有意义的方式修改序列的值。
  • 使用auto const &的只读访问。
  • 使用auto工作与(修改)的副本。

You also mention auto constwith no reference. This works, but it's not very commonly used because there is seldom an advantage to read-only access to something that you already own.

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

回答by phantom

Yes, it is correct to use autoand auto&for local variables. When getting the return type of a function, it is also correct to use auto&. This applies for range based for loops as well.

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

General rules for using autoare:

使用的一般规则auto是:

  • Choose auto xwhen you want to work with copies.
  • Choose auto &xwhen you want to work with original items and may modify them.
  • Choose auto const &xwhen you want to work with original items and will not modify them.
  • 选择auto x何时使用副本。
  • 选择auto &x何时使用原始项目并可以修改它们。
  • 选择auto const &x何时使用原始项目并且不修改它们。

You can read more about the auto specifier here.

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

回答by vsoftco

autouses the same mechanism of type deduction as templates, the only exception that I am aware of being that of brace-init lists, which are deduced by autoas std::initializer_list, but non-deduced in a template context.

auto使用与模板相同的类型推导机制,我知道的唯一例外是花括号初始化列表,它由autoas推导std::initializer_list,但在模板上下文中未推导。

auto x = expression;

works by first stripping all reference and cv qualifiers from the type of the right hand side expression, then matching the type. For example, if you have const int& f(){...}then auto x = f();deduces xas int, and notconst int&.

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

The other form,

另一种形式,

auto& x = expression

does not stripthe cv-qualifiers, so, using the example above, auto& x = f()deduces xas const int&. The other combinations just add cv qualifiers.

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

If you want your type to be always deduced with cv-ref qualifiers, use the infamous decltype(auto)in C++14, which uses the decltypetype deduction rules.

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

So, in a nutshell, if you want copies, use auto, if you want references, use auto&. Use constwhenever you want additional const-ness.

因此,简而言之,如果您想要副本,请使用auto,如果您想要引用,请使用auto&. 使用const时,你想要更多的const-ness。



EDITThere is an additional use case,

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

auto&& x = expression;

which uses the reference-collapsing rules, same as in the case of forwarding references in template code. If expressionis a lvalue, then xis a lvalue reference with the cv-qualifiers of expression. If expressionis a rvalue, then xis a rvalue reference.

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

回答by tweej

When creating local variables, is it correct to use (const) auto& or auto?

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

Yes. The auto is nothing more than a compiler-deduced type, so use references where you would normally use references, and local (automatic) copies where you would normally use local copies. Whether or not to use a reference is independent of type deduction.

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

Where SomeMethod() returns a non-primitive value - maybe another user-defined type. My understanding is that const auto& result is correct since the result returned by SomeMethod() would call the copy constructor for the returned type. Please correct me if I am wrong.

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

Legal? Yes, with the const. Best practice? Probably not, no. At least, not with C++11. Especially not, if the value returned from SomeMethod() is already a temporary. You'll want to learn about C++11 move semantics, copy elision, and return value optimization: https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by-value/

合法的?是的,使用常量。最佳实践?可能不是,不是。至少,不是 C++11。尤其是,如果从 SomeMethod() 返回的值已经是临时值。您需要了解 C++11 移动语义、复制省略和返回值优化:https: //juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by-价值/

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

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

https://isocpp.org/wiki/faq/ctors#return-by-value-optimization

https://isocpp.org/wiki/faq/ctors#return-by-value-optimization

What about for primitive types? I assume const auto sum = 1 + 2; is correct.

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

Yes, this is fine.

是的,这很好。

Does this also apply to range based for loops?

for(const auto& object : objects)

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

for(const auto& object : 对象)

Yes, this is also fine. I write this sort of code at work all the time.

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