Re-acquired move-constructibility after inheritance

Consider the following snippet:

#include <iostream>
#include <type_traits>

class base
{
public:

    base(const base &) = default;
    base(base &&) = delete;
};

class daughter : public base
{
};

int main()
{
    std :: cout << std :: is_move_constructible <daughter> :: value << std :: endl;
}

I've been staring at it all morning, but I just can't figure out why it outputs:

1

Class base is explicitly not move constructible (is_move_constructible is actually false on base), and daughter inherits from it. Why should it magically become move constructible again? What would the default move constructor of daughter even look like?

728x90

1 Answers Re-acquired move-constructibility after inheritance

Class base is explicitly not move constructible

But it is. That type trait merely checks that daughter d2( std::move(d1) ); is well-formed for any two objects. You may have explicitly deleted the move c'tor in base, but in daughter it's only implicitly deleted. So overload resolution will correctly choose the copy c'tor instead.

[over.match.funcs]

8 A defaulted move constructor or assignment operator ([class.copy]) that is defined as deleted is excluded from the set of candidate functions in all contexts.

If you really want daughter to be non-movalbe, you need to explicitly delete the move constructor of daughter itself. Then overload resolution will hit an explicitly deleted function, that will make the construct being checked ill-formed.

5 months ago