当我在Visual Studio 2019中声明这样的基本结构时:
struct Test
{
Test(Test &&test) = default;
};
以下断言失败:
static_assert(std::is_trivially_copyable<Test>::value, "Test is not trivially copyable !");
这个:
struct Test
{
Test(const Test &test) = default;
};
或这个:
struct Test
{
};
显然可以。但是我真的不明白第一个发生了什么。就复制行为而言,这与其他之间有何区别?
答案 0 :(得分:2)
这是Visual Studio中现代版本C ++的错误,但从技术上讲,它不是原始版本C ++ 11的错误。
首先,当我提到Test
时,是在谈论您的第一个定义。这样我们就很清楚了。
除非显式指定,否则通过显式默认Test
的move构造函数,将导致编译器隐式delete
复制构造函数和赋值运算符。该规则背后的思想是,如果您竭尽全力明确地default
构造函数,那么您可能正试图用这种说法。
仅具有默认移动构造函数的类型看起来类似于仅移动类型,因此标准假定这就是您想要的。而且,如果您不想这样做,则需要将其拼写清楚。
复制构造函数不会发生这种情况,因为移动被认为是复制的一种特殊形式。如果类型是默认可复制的,则它在逻辑上是默认可移动的,因此将move构造函数隐式保留为默认是有意义的。
这样的事情就是为什么您不应该default
使用特殊的成员函数,除非您不知道这会如何影响其他成员或者您打算default/delete
/实现所有其他成员函数。
在C ++ 11的初始版本中,默认移动构造函数的复制隐式删除将使Test
不可TriviallyCopyable。但是,琐碎可复制性的措词在C ++ 14 via a defect report周围已更改。即使删除了某些复制/移动构造函数/赋值运算符,新的措辞也允许类型是TriviallyCopyable。因此,使Test
是TriviallyCopyable的。缺陷修复程序通常是追溯性应用的,因此从技术上讲,现代的C ++ 11实现也应该起作用。
Visual Studio从未更改以适应新的措辞。因此是错误。