C++ “a”是什么;“常规类型”;在移动语义的上下文中?

C++ “a”是什么;“常规类型”;在移动语义的上下文中?,c++,generics,c++11,move-semantics,C++,Generics,C++11,Move Semantics,作为满足有关复制和相等的某些属性的类型。现在,C++11已经将移动语义添加到泛型编程领域,Stepanov的定义不再完整。根据Stepanov的论文,我正在寻找一个关于常规类型的很好的参考资料,其中包括它们与移动语义的交互。添加移动赋值和移动复制构造函数,以及所有其他内置类型的操作符,我想你已经有了它。通用编程的约束最好用表达式来表述。复制性约束的更现代的表现形式是两个语句都应有效: T b = a; 及 其中,a是类型为T或const T的左值,ra是类型为T或const T的右值。(具有类

作为满足有关复制和相等的某些属性的类型。现在,C++11已经将移动语义添加到泛型编程领域,Stepanov的定义不再完整。根据Stepanov的论文,我正在寻找一个关于常规类型的很好的参考资料,其中包括它们与移动语义的交互。

添加移动赋值和移动复制构造函数,以及所有其他内置类型的操作符,我想你已经有了它。

通用编程的约束最好用表达式来表述。复制性约束的更现代的表现形式是两个语句都应有效:

T b = a;

其中,
a
是类型为
T
const T
的左值,
ra
是类型为
T
const T
的右值。(具有类似的岗位条件。)

我相信这个提法符合文件的精神。请注意,C++03已经使用了诸如左值和右值之类的概念,因此我们所表达的约束要求类似于
T source();T b=源()是有效的——当然是一些看起来合理的东西

在这些约束条件下,C++11没有太多变化。特别值得注意的是,这种(病理)类型是不规则的:

struct irregular {
    irregular() = default;
    irregular(irregular const&) = default;
    irregular& operator=(irregular const&) = default;

    irregular(irregular&&) = delete;
    irregular& operator=(irregular&&) = delete;
};
因为像
这样的东西是不规则的;不规则b=a
不规则源()时有效;不规则b=源()不是。这是一种有点可复制(即复制可分配)的类型,但还不够。[这在某种程度上被认为是一个缺陷,并计划在C++1y中进行更改,这样的类型实际上是可复制的。]

更进一步地说,对于post条件,即副本在某种意义上必须与原件(或者,对于右值,与副本之前的原件)相等才能保持,移动特殊成员只能是相应副本特殊成员的“优化”。另一种说法是,复制语义是移动语义的细化。这意味着断言必须包含以下内容:

T a;
T b = a;
T c = std::move(a);
assert( b == c );
也就是说,无论我们是通过复制“请求”(即,涉及左值源的表达式)还是通过移动请求(涉及右值源的表达式),我们都必须得到相同的结果,而不管“实际”发生了什么(如果涉及复制特殊成员还是移动特殊成员)

有趣的是,
std::is\u copy\u constructible
等特征过去被称为
std::has\u copy\u constructive
,但是被重新命名以强调表达式而不是内在属性:类似于
std::is\u copy\u constructible::value&&std::is\u move\u assignable::value
是真的,不管
int
没有构造函数或赋值运算符


我建议您通过在表达式级别表达约束来真正进行泛型编程,因为例如,移动构造函数的存在或不存在对于可复制构造的类型来说既不充分也不必要。

摘要:

对于C++11,我将包括:

  • 移动选择器(
    noexcept
  • 移动分配(
    noexcept

  • 总订单(
    Operator要使类型成为常规类型,即使在C++11中,类型也必须是可复制的吗?这可以通过使用资源(如流或图像)的类型实现吗?我想后一个问题的答案是否定的,但前一个问题呢?我更新了链接。是的,即使在C++11中,类型也必须是可复制的,才能被视为常规类型,甚至是使用资源(图像、容器等)也必须是可复制的。如果复制的结果是无效的或断开的关系(视频尚未联机),我们可能会选择不对表示关系的类型实施复制。我更喜欢将此类类型称为不完整,而不是“不规则”。除了可移动外,您是否建议所有类型的文件都可复制?我认为这比通常可能的情况下更为努力,对吗?我确实建议所有类型的文件都可复制-是的,这是“最大努力”。例外情况是:(1)表示可能在复制时被切断或失效的关系的对象-您可以选择不在此类对象上实现复制,但它们应仅用作构建其他常规类型的机制。(2)相等不完整的对象-通常可以通过使对象不可变来实现复制。(3)库中的类型(平台,操作系统)不可复制-可复制是一个可传递属性,因此包含此类类型的对象不可复制。请使用不变性或等式完整性还原副本。
    
    T a;
    T b = a;
    T c = std::move(a);
    assert( b == c );