创建局部变量时,使用(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
auto并auto &&涵盖大多数情况:
使用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使用相同的类型推导机制作为模板,我知道的唯一例外是brace-init列表,它是由autoas 推导出来的std::initializer_list,但在模板上下文中是非推导的.
auto x = expression;
Run Code Online (Sandbox Code Playgroud)
首先从右侧表达式的类型中剥离所有引用和cv限定符,然后匹配类型.例如,如果你有,const int& f(){...}那么auto x = f();推断x为int,而不是 const int&.
另一种形式,
auto& x = expression
Run Code Online (Sandbox Code Playgroud)
不会剥离 cv限定符,因此,使用上面的示例,auto& x = f()推导x为const 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是右值参考.