In the below code, is_copy_constructible_v
returns true, but MainClass' copy constructor is marked as deleted.
Trying to call the copy constructor is be a compilation error.
So how come that is_copy_constructible_v
does not see it?
class BaseClass {};
class MainClass : public BaseClass {
public:
MainClass(MainClass&) = delete;
MainClass(const BaseClass& rhs)
{
}
};
int main()
{
MainClass first{{}};
//This line will not compile because MainClass::MainClass(MainClass&) is a deleted function
//MainClass second{first};
auto mainclass_is_constructible = std::is_copy_constructible_v<MainClass>;
//This assert fails because is_copy_constructible_v returns true
static_assert((std::is_copy_constructible_v<MainClass>) == 0);
}
This was found from having unit tests for that check if a given class is copyable/movable.
They work fine, but not after adding the equivalent of MainClass(const BaseClass& rhs)
in real code.
If instead we have MainClass(const BaseClass& rhs, int value)
, then is_copy_constructible_v
will work.
What would happen given an std::vector<MainClass>
, if we also delete the move ctor/assignment? Won't the vector make use of is_copy_constructible_v
to detect how to operate best, and receive a wrong answer?
Many thanks
MainClass
has a MainClass::MainClass(const BaseClass& rhs)
, which makes constructing MainClass
from a const lvalue possible, e.g.
const MainClass first{{}};
// This line will compile because MainClass::MainClass(const BaseClass& rhs) is usable
// a MainClass could be bound to const BaseClass&
MainClass second{first};
And std::is_copy_constructible
performs the check as:
provides a member constant value equal to
std::is_constructible<T, const T&>::value
.
Note that it's checking whether T
could be constructed from const T&
, then it yields true
for MainClass
.
If you declare the copy constructor as:
MainClass(const MainClass&) = delete;
You'll get the result false
.
What would happen given an
std::vector<MainClass>
It'll use the MainClass::MainClass(const BaseClass& rhs)
(for push_back
or reallocation etc). If it's not what you expect you have to reconsider the design.