【问题标题】:Why class derived from non-movable class is itself move constructible? [duplicate]为什么从不可移动类派生的类本身是可移动构造的? [复制]
【发布时间】:2021-08-25 00:33:53
【问题描述】:

根据 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&amp;参数的复制构造函数的类型,满足std::is_move_constructible
  • 这并不能解释为什么is_move_constructible_v&lt;NonMovable&gt;false
  • @S.M.在这种情况下,std::cout &lt;&lt; std::is_move_constructible_v&lt;NonMovable&gt; &lt;&lt; "\n"; 将是1,但它显示0
  • 问题是关于第二种情况。 AFAIK删除的构造函数也不涉及没有构造函数的类。
  • NonMovable 的情况下,移动构造函数被显式删除。显式删除的函数仍然参与重载决议(但如果它最终获胜,则会出现编译器错误)。但是在Derived 中,移动构造函数默认为已删除,因此它根本不参与。 (因此无法赢得它不玩的游戏)。 "A defaulted move special member function that is defined as deleted is excluded from the set of candidate functions in all contexts.

标签: c++ c++11 move-semantics typetraits


【解决方案1】:

关键子句似乎如下:

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

...

定义为已删除的默认移动构造函数被忽略 重载决议。 [注意:删除的移动构造函数将 否则会干扰从可以使用的右值 的初始化 而是复制构造函数。 - 结束注释]

强调我的。被删除的移动构造函数被简单地排除在重载决议之外,派生类的构造函数最终选择了基类的复制构造函数而不是移动构造函数。

【讨论】:

    猜你喜欢
    • 2017-01-01
    • 2016-10-06
    • 2017-10-06
    • 2018-06-28
    • 2011-10-15
    • 2020-10-07
    • 1970-01-01
    • 2017-01-16
    相关资源
    最近更新 更多