从不可移动类派生的类为什么可以自身进行移动构造?

6
根据cppreference的说法,从一个不可移动的类派生出来的类也应该是不可移动的。那么为什么std::is_move_constructible_v返回派生类为true呢?
class NonMovable{
    public:
        NonMovable(const NonMovable&) = default;
        NonMovable(NonMovable&&) = delete;
        
        NonMovable& operator = (const NonMovable&) = default;
        NonMovable& operator = (NonMovable&&) = delete;
        
        NonMovable() = default;
};

class Derived : public NonMovable{};

int main(){
    std::cout << std::is_move_constructible_v<NonMovable> << "\n"; // 0
    std::cout << std::is_move_constructible_v<Derived> << "\n"; // 1
}

没有移动构造函数但有接受const T&参数的复制构造函数的类型,满足std :: is_move_constructible - 273K
1
这并没有解释为什么 is_move_constructible_v<NonMovable>false - Nathan Pierson
在这种情况下,std::cout << std::is_move_constructible_v<NonMovable> << "\n"; 应该是 1,但它显示为 0 - François Andrieux
问题涉及第二种情况。据我所知,删除的构造函数并不意味着类没有构造函数。 - 273K
3
对于NonMovable情况,移动构造函数被显式删除。显式删除的函数仍然参与重载决议(但如果它最终获胜,你会得到一个编译器错误)。但是在Derived中,移动构造函数被默认为删除,因此根本不参与(因此无法赢得没有参与的游戏)。 "将已定义为已删除的默认移动特殊成员函数从所有上下文的候选函数集排除。" - Raymond Chen
显示剩余2条评论
1个回答

3
关键条款似乎是以下内容:

复制/移动构造函数 [class.copy.ctor]

...

定义为已删除的默认移动构造函数将被重载决议所忽略。[注意: 已删除的移动构造函数会干扰使用复制构造函数而不是移动构造函数进行rvalue初始化的操作。—注释]

强调我的部分。已删除的移动构造函数仅从重载决议中排除,派生类的构造函数最终选择基类的复制构造函数而不是移动构造函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接