C合成移动构造函数如何受到volatile和virtual成员的影响?

前端之家收集整理的这篇文章主要介绍了C合成移动构造函数如何受到volatile和virtual成员的影响?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
看下面的代码
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 clearvolatile 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).

猜你在找的C&C++相关文章