创建局部变量时,使用(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)
答案 0 :(得分:56)
auto
和auto &&
涵盖了大多数情况:
需要本地副本时使用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)
是的,将auto
和auto&
用于局部变量是正确的。
获取函数的返回类型时,使用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)
是的,这也没关系。我一直都在写这种代码。