According to cppreference and this answer, C++ should not automatically generate a move constructor if there is a user declared destructor. Checking this in practice with Clang, however, I see an auto-generated move constructor. The following code prints "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;
}
Am I misunderstanding "there is no user-declared destructor" or std::is_move_constructible? I'm compiling with '-std=c++14' and Apple LLVM version 7.0.2 (clang-700.1.81).
Types without a move constructor, but with a copy constructor that accepts const T&
arguments, satisfy std::is_move_constructible
and implicitly-declared copy constructor has the form T::T(const T&)
.
If implicitly-declared copy constructor is deleted, std::is_move_constructible
is not satisfied as below.
#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;
}
For C++11 code, the accepted answer by @Alper is fine. But to make your code future-proof, note that as of Clang 3.7 (no idea which Apple version that corresponds to, sure you can find out), using -std=c++1z -Wdeprecated
will generate the following
warning: definition of implicit copy constructor for 'TestClass' is deprecated because it has a user-declared destructor [-Wdeprecated]
~TestClass()
^
Live Example
The relevant part of the draft C++1z Standard N4567 is
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.
Deprecated means that a future Standard may stop generating an implicit copy constructor in case of a user-declared destructor. It's best practice to change your code today to not rely on deprecated behavior (i.e. in this case, making the copy-behavior of your class explicit).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With