创建局部变量时,使用(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列表,它是由auto
as 推导出来的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
是右值参考.