C++ Автоматически Генерирует Конструктор Перемещения С Объявленным Пользователем Деструктором?

по данным cppreference и ответ, 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 ответов


типы без конструктора перемещения, но с конструктором копирования, который принимает 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()
  ^

Видео

соответствующая часть проекта стандарта C++1z N4567 и

12.8 копирование и перемещение объектов класса [класс.копировать]

7 Если определение класса явно не объявляет конструктор копирования, a неявное объявляется неявно. Если определение класса объявляется конструктор перемещения или перемещения оператора присваивания, в неявно объявленный конструктор копирования определяется как удаленный; в противном случае, он определяется как defaulted (8.4). последний случай устарел, если класс оператор назначения копии, объявленный пользователем, или пользователь-заявил деструктор!--7-->.

Deprecated означает, что будущий стандарт может прекратить генерировать неявный конструктор копирования в случае объявленного пользователем деструктора. Рекомендуется изменить код не полагаться на устаревшее поведение (т. е. в этом случае делать поведение копирования вашего класса явным).