In the following test code, I understand why the class is still seen as move constructable, even though the default move constructor and assignment operator would not be implicitly generated by the compiler.
Understanding based on the following from cppreference.com:
Types without a move constructor, but with a copy constructor that accepts
const T&
arguments, satisfystd::is_move_constructible
— [Ref]
#include <type_traits>
#include <concepts>
#include <cstdbool>
struct DestructableMock {
DestructableMock() : m_value(0x5a5a5a5a), m_output_debug(false) { }
DestructableMock(unsigned int value) : m_value(value), m_output_debug(false) { }
DestructableMock(unsigned int value, bool output_debug) :
m_value(value), m_output_debug(output_debug) {
}
~DestructableMock() {
}
DestructableMock(const DestructableMock &src) {
m_output_debug = src.m_output_debug;
m_value = src.m_value;
}
//DestructableMock(DestructableMock &&src) = delete;
DestructableMock& operator=(const DestructableMock &other) {
if (&other != this) {
m_value = other.m_value;
m_output_debug = other.m_output_debug;
}
return *this;
}
unsigned int m_value;
bool m_output_debug;
};
static_assert(!std::is_trivially_destructible_v<DestructableMock>);
static_assert(std::is_copy_constructible_v<DestructableMock>);
// Types without a move constructor, but with a copy constructor that accepts const T& arguments,
// satisfy std::is_move_constructible.
static_assert(std::is_move_constructible_v<DestructableMock>);
// But it is not trivially move constructable
static_assert(!std::is_trivially_move_constructible_v<DestructableMock>);
static_assert(std::is_move_assignable_v<DestructableMock>);
static_assert(std::is_move_assignable_v<DestructableMock>);
int main() {
return 0;
}
See code on programiz here
So, I can understand why static_assert(std::is_move_constructible_v<DestructableMock>);
passes: there is no move constructor but there is a copy constructor accepting a const
reference.
However, if I uncomment the line that explicitly deletes the move constructor, the same assertion fails. Why is this? There is still the “copy constructor that accepts const T&
arguments”, so why is it not seen as move constructable still?
My compiler version is gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0
btw
1
However, if I uncomment the line that explicitly deletes the move constructor, the same assertion fails. Why is this?
For deleted functions:
If the function is overloaded, overload resolution takes place first,
and the program is only ill-formed if the deleted function was
selected:
That means the explicitly deleted move constructor will be selected in overload resolution, then compilation fails as it’s deleted.
For the 1st case, the class has only the copy constructor, then overload resolution selects it as it also accepts rvalues, everything is fine.
4