使用std :: move的未定义行为

Ast*_*nog 6 c++ c++11

从cppreference 的移动页面

除非另行指定,否则已移出的所有标准库对象都将处于有效但未指定的状态.也就是说,只有没有前置条件的函数(例如赋值运算符)才能在对象移动后安全地使用

因此,从同一页面上的示例,下面的代码被视为未定义的行为

vector<string> v_string;
string example = "example";
v_string.push_back(move(example));
cout << example << endl;
Run Code Online (Sandbox Code Playgroud)

MSVC将不会在控制台上输出任何内容,但是如果我这样做的话

vector<int> v_int;
int number = 10;
v_int.push_back(move(number));
cout << number << endl;
Run Code Online (Sandbox Code Playgroud)

将输出10.这是否有理由发生?或者它总是未定义的行为?

Joe*_*Joe 10

未指定并不意味着未定义.

根据C++ 11标准,第17.3.26节:

有效但未指定的状态 是未指定的对象状态,除了满足对象的不变量,并且对象上的操作的行为与其类型的指定相同

由于对象处于有效状态,您可以将其流式传输到输出,因为流没有其他前提条件.然而,所印刷的是未指定的,因此它可能只是打印,或打印您的父亲闻到接骨木果.您不能安全地做的是使用具有附加前提条件的函数,例如back()另外要求字符串非空.有效字符串可以为空.

对于未指定但有效的状态,包含旧值是完全可接受的选项.在基本类型的情况下,例如int简单副本只是执行移动的最有效方式.

还应注意,int不是标准库对象,而是基本类型(如第3.9.1节中所定义).因此,您的报价不适用.

  • 作为参考,这里是标准的定义:"除了满足对象的不变量并且对象上的操作按照其类型指定的行为之外,未指定的对象状态" (2认同)