【发布时间】:2016-12-12 11:35:16
【问题描述】:
再讲一次,但相关问题没有回答我的问题。
标准很明确:
12.8 复制和移动类对象,
§9
如果类 X 的定义没有显式声明移动构造函数,则当且仅当
— X 没有用户声明的复制构造函数,
— X 没有用户声明的复制赋值运算符,
— X 没有用户声明的移动赋值运算符,
— X 没有用户声明的析构函数,并且
— 移动构造函数不会被隐式定义为已删除。
[注意:当移动构造函数没有被隐式声明或显式提供时,否则会调用移动构造函数的表达式可能会调用复制构造函数。 ——尾注]
所以,在注意到末尾的“注释”之前,我预计这段代码会编译失败(虽然我知道,移动 应该 退回到复制):
#include <iostream>
using std::cout;
class c
{
public:
c() { cout << "c::c()\n"; }
c( std::initializer_list< int > ) { cout << "c::c( std::initializer_list )\n"; };
c( const c& ) { cout << "c::c( const c& )\n"; }
c& operator=( const c& ) { cout << "c& c::operator=( const c& )\n"; return *this; }
~c() { cout << "c::~c()\n"; }
void f() {}
};
void f( c&& cr ) { cout << "f()\n"; cr.f(); }
int main()
{
c x;
f( std::move( x ) );
return 0;
}
然后我看到了最后的注释,但我还是很惊讶,上面的代码输出:
c::c()
f()
c::~c()
注意“缺失”c::c( const c& )。然后我添加了
c( c&& ) = delete;
c& operator=( c&& ) = delete;
结果还是一样。
我错过了什么?
$ g++ --version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.2) 5.4.0 20160609
编译器标志:-s -O0 -march=native -pthread -std=c++11 -Wall -Wextra -DNDEBUG。
【问题讨论】:
-
cr是尚未被任何构造函数使用的右值 reference... -
@W.F. - 哦,天哪,请将此作为答案发布。你非常正确。 (添加
c xx( std::move( x ) );而不是使用f( c&& )会产生预期的行为。 -
这是一个 nop 问题 XD
-
@Stargateur - “nop question”?
-
@KirilKirov en.wikipedia.org/wiki/NOP。因为你的例子没有问题:p
标签: c++ move move-constructor implicit-constructor