根据cppreference和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;
}
我是否误解“没有用户声明的析构函数”或std :: is_move_constructible?我正在编译'-std = c ++ 14'和Apple LLVM版本7.0.2(clang-700.1.81)。
答案 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()
^
C ++ 1z标准N4567草案的相关部分是
12.8复制和移动类对象[class.copy]
7如果类定义没有显式声明一个拷贝构造函数,那么 隐式声明非显式的。如果是类定义 声明一个移动构造函数或移动赋值运算符 隐式声明的复制构造函数被定义为已删除;除此以外, 它被定义为默认值(8.4)。 如果是,则不推荐使用后一种情况 class具有用户声明的复制赋值运算符或用户声明的 析强>
不推荐使用意味着在用户声明的析构函数的情况下,未来的Standard可能会停止生成隐式复制构造函数。最佳做法是将您的代码今天更改为不依赖于弃用的行为(即在这种情况下,使您的类的复制行为显式化)。