[英]Safety of auto when std::move ing from a returned reference of a value
我需要放心,无论何时使用以下方法来分配或列表初始化auto
键入的命名变量:
std::move
()ed返回对变量的引用 在表达式之后,原点超出范围的地方是A安全/ B不安全。 示例代码:
#include <iostream>
#include <string>
#include <deque>
#include <utility>
int main() {
std::deque<std::string> container {"foo"};
auto elementB = container.front(); //B I assume this is unsafe
auto elementA = std::move(container.front());//A I assume this is safe
container.pop_front();
std::cout << "A: " << elementA << " B: " << elementB << "\n";
}
据我所知,表达式B生成赋值的左值,因此elementB
的类型是左值引用,也称为std::string&
,因此这是不安全的。
执行代码时,“ A:foo B:”的输出也表明了这一点。 ( https://ideone.com/wKKbdK )更新:对不起,我忘了我移动了它,所以我更改了顺序,现在输出为例外,抱歉。
但是,我不确定的最麻烦的事情是表达式A:在std::move
之后,我假设我得到了既是rvalue又是glvalue的xvalue,因此我不确定该类型的标准化行为(如果有)推导elementA
。
因为从lvalues我几乎可以确定它的UB,而lvalues是glvalues,xvalues是它们的一部分,那么elementA
的类型将是std::string&&
,这是不安全的,对吗? (除非const && AFAIK例外)
总结一下: elementA的使用是否是安全的标准化行为,其类型将是什么?
使用elementA是否安全,规范?
是。
...它的类型是什么?
它的类型将是std::string
。 auto
类型推导的工作方式类似于模板类型推导,其中包括删除参考的“参考性”。 std::move(container.front())
返回xvalue的事实在这里并没有太大改变。 它是一个“过期”值,您可以(a)移动构造一个新对象(如您当前所做的那样)(b)将其绑定到const
限定的引用,或者(c)将其绑定到一个rvalue-reference。 在这里,(b)和(c)都可以工作,但意义不大,因为它们掩盖了什么都没有移走的事实(感谢@MM在这里纠正了我)。 例:
auto elementA = std::move(container.front());
// Error, can't bind to non-const reference:
// auto& doesntWork = std::move(container.front());
auto&& thisWorks = std::move(container.front());
const auto& thisWorksToo = std::move(container.front());
请注意,正如@MM在注释中指出的那样,一旦container.pop_front();
后面的两个引用将悬而未决container.pop_front();
遇到。
还要注意,将elementB
为std::string
并不能帮助您取消引用移出的对象(由container.front()
返回),这一点应避免。
您的代码很好,因为elementA
和elementB
都elementB
导出为string
,而不是引用( string&
或string&&
)。
给定auto elementA
,初始化器的引用部分将被忽略。 如果要引用elementA
或elementB
,则必须明确指定,例如auto&& elementA
或auto& elementB
。
您可能将值类别与类型混淆; 他们是独立的。 初始化程序的值类别,即它是一个左值或右值,不会影响类型推导 。 在您的代码中,给定auto elementA
, elementA
将为std::string
类型,给定auto& elementA
,其类型将为std::string&
,给定auto&& elementA
,其类型将为std::string&&
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.