继承后重新获得移动可构造性
Re-acquired move-constructibility after inheritance
考虑以下片段:
#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;
}
我盯着它看了一上午,就是想不通为什么输出:
1
Class base
显然不可移动构造(is_move_constructible
实际上是 false
on base
),并且 daughter
继承自它.为什么它会神奇地再次变得可移动? daughter
的默认移动构造函数会是什么样子?
Class base is explicitly not move constructible
但确实如此。该类型特征仅检查 daughter d2( std::move(d1) );
对于任何两个对象是否格式正确。您可能已经在 base
中显式删除了 move c'tor,但在 daughter
中它只是隐式删除。因此重载解析将正确地选择复制 c'tor。
[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.
如果你真的想要daughter
是非移动的,你需要明确删除daughter
本身的移动构造函数。然后重载决议将命中一个显式删除的函数,这将使被检查的构造格式错误。
考虑以下片段:
#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;
}
我盯着它看了一上午,就是想不通为什么输出:
1
Class base
显然不可移动构造(is_move_constructible
实际上是 false
on base
),并且 daughter
继承自它.为什么它会神奇地再次变得可移动? daughter
的默认移动构造函数会是什么样子?
Class base is explicitly not move constructible
但确实如此。该类型特征仅检查 daughter d2( std::move(d1) );
对于任何两个对象是否格式正确。您可能已经在 base
中显式删除了 move c'tor,但在 daughter
中它只是隐式删除。因此重载解析将正确地选择复制 c'tor。
[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.
如果你真的想要daughter
是非移动的,你需要明确删除daughter
本身的移动构造函数。然后重载决议将命中一个显式删除的函数,这将使被检查的构造格式错误。