C ++自动使用用户声明的析构函数生成移动构造函数?

时间:2016-02-06 09:44:56

标签: c++ destructor c++14 move-constructor

根据cppreferencethis answer,如果用户声明了析构函数,则C ++应该自动生成移动构造函数。但是,在实践中用Clang检查这个,我看到了一个自动生成的移动构造函数。以下代码打印“is_move_constructible:1”:

#include <iostream>
#include <type_traits>

struct TestClass
{
  ~TestClass()
  {}
};

int main( int argc, char** argv )
{
  std::cout << "is_move_constructible: " << std::is_move_constructible<TestClass>::value << std::endl;
}

我是否误解“没有用户声明的析构函数”或std :: is_move_constructible?我正在编译'-std = c ++ 14'和Apple LLVM版本7.0.2(clang-700.1.81)。

2 个答案:

答案 0 :(得分:8)

没有移动构造函数但带有接受const T&参数的复制构造函数,满足std::is_move_constructible且隐式声明的复制构造函数的类型具有T::T(const T&)形式。

如果删除隐式声明的复制构造函数,则不满足std::is_move_constructible,如下所示。

#include <iostream>
#include <type_traits>

struct TestClass
{
  ~TestClass() {}
  TestClass(const TestClass&) = delete;
};

int main( int argc, char** argv )
{
  std::cout << "is_move_constructible: " << std::is_move_constructible<TestClass>::value << std::endl;
}

答案 1 :(得分:2)

对于C ++ 11代码,@ Alper接受的答案很好。但为了使您的代码能够面向未来,请注意,从Clang 3.7开始(不知道哪个Apple版本对应,确定您可以找到),使用-std=c++1z -Wdeprecated将生成以下内容

warning: definition of implicit copy constructor for 'TestClass' is deprecated because it has a user-declared destructor [-Wdeprecated]
  ~TestClass()
  ^

Live Example

C ++ 1z标准N4567草案的相关部分是

  

12.8复制和移动类对象[class.copy]

     

7如果类定义没有显式声明一个拷贝构造函数,那么   隐式声明非显式的。如果是类定义   声明一个移动构造函数或移动赋值运算符   隐式声明的复制构造函数被定义为已删除;除此以外,   它被定义为默认值(8.4)。 如果是,则不推荐使用后一种情况   class具有用户声明的复制赋值运算符或用户声明的   析

不推荐使用意味着在用户声明的析构函数的情况下,未来的Standard可能会停止生成隐式复制构造函数。最佳做法是将您的代码今天更改为不依赖于弃用的行为(即在这种情况下,使您的类的复制行为显式化)。