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 означает, что будущий стандарт может прекратить генерировать неявный конструктор копирования в случае объявленного пользователем деструктора. Рекомендуется изменить код не полагаться на устаревшее поведение (т. е. в этом случае делать поведение копирования вашего класса явным).