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

C++ Auto Generates Move Constructor With User Declared Destructor?

根据cppreference and this 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;
}

我是不是误会了"there is no user-declared destructor"或std::is_move_constructible?我正在使用“-std=c++14”和 Apple LLVM 版本 7.0.2 (clang-700.1.81) 进行编译。

没有移动构造函数但具有接受 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;
}

对于 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 Copying and moving class objects [class.copy]

7 If the class definition does not explicitly declare a copy constructor, a non-explicit one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is deprecated if the class has a user-declared copy assignment operator or a user-declared destructor.

弃用意味着未来的标准可能会在用户声明的析构函数的情况下停止生成隐式复制构造函数。最好的做法是 今天 更改您的代码以不依赖已弃用的行为(即在这种情况下,使您的 class 的复制行为明确)。