看下面的代码:
struct node
{
node();
//node(const node&); //#1
//node(node&&); //#2
virtual //#3
~node ();
node*
volatile //#4
next;
};
int main()
{
node m(node()); //#5
node n=node(); //#6
}
当使用gcc-4.6.1编译时,会产生以下错误:
g++ -g --std=c++0x -c -o node.o node.cc
node.cc: In constructor node::node(node&&):
node.cc:3:8: error: expression node::next has side-effects
node.cc: In function int main():
node.cc:18:14: note: synthesized method node::node(node&&) first required here
据了解,编译器无法在第6行上创建默认移动或复制构造函数,如果我取消注释行#1或#2,它会编译好,这是很清楚的.代码编译没有c 0x选项,所以错误与默认移动构造函数相关.
但是,节点类中什么阻止默认移动构造函数被创建?如果我注释任何行#3或#4(即使析构函数非虚拟或使数据成员非易失性)它再次编译,这两个组合是否使其不编译?
另一个难题,第5行不会导致编译错误,与第6行有什么不同? 这是否具体针对gcc?或gcc-4.6.1?
解决方法
[C++11: 12.8/9]: If the definition of a class X does not explicitly declare a move constructor,one will be implicitly declared as defaulted if and only if
X does not have a user-declared copy constructor,
X does not have a user-declared copy assignment operator,
X does not have a user-declared move assignment operator,
X does not have a user-declared destructor,and
- the move constructor would not be implicitly defined as deleted.
[ Note: When the move constructor is not implicitly declared or explicitly supplied,expressions that otherwise would have invoked the move constructor may instead invoke a copy constructor. —end note ]
这就是为什么你的#3打破了综合.
另外it’s far from clear是volatile types (including your node* volatile ) are trivially copyable;可以得出结论,it is implementation-defined whether they are or not,在你的情况下,似乎它们不是.
至少,GCC made it stop working quite deliberately在v4.7中,有一个提案到v4.6.1,我只能假定继续前进…
所以,给出如下:
[C++11: 12.8/11]: An implicitly-declared copy/move constructor is an inline public member of its class. A defaulted copy/move constructor for a class X is defined as deleted (8.4.3) if X has:
- a variant member with a non-trivial corresponding constructor and
X is a union-like class, a non-static data member of class type M (or array thereof) that cannot be copied/moved because overload resolution (13.3),as applied to M ’s corresponding constructor,results in an ambiguity or a function that is deleted or inaccessible from the defaulted constructor,
- a direct or virtual base class
B that cannot be copied/moved because overload resolution (13.3),as applied to B ’s corresponding constructor,
- any direct or virtual base class or non-static data member of a type with a destructor that is deleted or inaccessible from the defaulted constructor,
- for the copy constructor,a non-static data member of rvalue reference type,or
- for the move constructor,a non-static data member or direct or virtual base class with a type that does not have a move constructor and is not trivially copyable.
…这就是为什么你的#4也是打破综合性,独立于#3.
对于#5,实际上并不是一个节点的声明,而是一个名为m的函数的声明 – 这就是为什么它不再现与节点构造相关的症状(这被称为Most Vexing Parse).
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|