【问题标题】:C++ Auto Generates Move Constructor With User Declared Destructor?C ++自动生成带有用户声明的析构函数的移动构造函数?
【发布时间】:2016-05-16 08:08:43
【问题描述】:

根据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) 进行编译。

【问题讨论】:

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


    【解决方案1】:

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

    如果隐式声明的复制构造函数被删除,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;
    }
    

    【讨论】:

      【解决方案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)。 如果 类具有用户声明的复制赋值运算符或用户声明的 析构函数

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

      【讨论】:

      • 我的clang版本是clang version 5.0.0-3~16.04.1 (tags/RELEASE_500/final)。我也使用选项-std=c++1z -Wdeprecated,但它没有给我任何警告。
      猜你喜欢
      • 2019-03-09
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 2016-12-28
      • 2012-03-08
      • 1970-01-01
      • 2012-01-07
      相关资源
      最近更新 更多