swap
: template <typename T>
void swap(T& a, T& b)
{
T c = std::move(a); // line 1
a = std::move(b); // line 2: assignment to moved-from object!
b = std::move(c); // line 3: assignment to moved-from object!
}
显然,必须可以将其分配给移出的对象,否则第2行和第3行将失败。那么我还能对移出的对象做什么呢?
(顺便问一下,为什么用
T c = std::move(a);
代替第1行中的T c(std::move(a));
?)#1 楼
移动的对象以未指定但有效的状态存在。这表明,尽管该对象可能无法再执行更多操作,但其所有成员函数仍应表现出已定义的行为(包括operator=
),并且其所有成员均处于已定义的状态,并且仍然需要销毁它。该标准没有给出具体定义,因为它对于每个UDT都是唯一的,但是您可以找到标准类型的规范。一些类似的容器是相对明显的-它们只是移动内容,而空容器是明确定义的有效状态。 侧面说明:我相信它是
T c = std::move(a)
,因此,如果移动构造函数(如果未提供移动,则为复制构造函数)是显式的,该函数将失败。 br />#2 楼
17.6.5.15 [lib.types.movedfrom]C ++标准库中定义的类型的对象可以从
(12.8)中移出。可以明确指定移动操作,也可以隐式生成
。除非另有说明,否则此类移出的对象应置于有效但未指定的状态。
当对象处于未指定的状态时,可以对没有先决条件的对象。如果存在要执行的先决条件操作,则无法直接执行该操作,因为您不知道对象的未指定状态是否满足先决条件。
通常可以执行的操作示例没有先决条件:
销毁
分配
get,
empty
,size
操作示例通常具有前提条件:
取消引用
pop_back
此答案现在以视频格式显示在以下位置:http://www.youtube.com / watch?v = vLinb2fgkHk&t = 47m10s
评论
但是我可以像检查其他任何对象一样简单地检查前提条件,对吗?
– fredoverflow
2011年8月11日15:17
@FredOverflow当然,只要这些检查本身没有任何先决条件。
–克里斯蒂安·劳(Christian Rau)
2011年8月11日15:18
@Chris:但是,这与普通的非移动对象有何不同?
– fredoverflow
2011年8月11日15:25
May-be应该是一个单独的问题,但这是否意味着:如果我有一个带有char *缓冲区的字符串;和int长度;成员,那么我的移动构造函数/赋值必须交换(或设置)两者的值?如果未指定长度(表示空值和大小返回无意义的值),还是可以的?
– UncleBens
2011年8月11日15:32
@ 6502:你没有道理。 C ++ 03类不会“违反C ++ 0x标准”,因为生成的移动ctor会违反该标准。而且C ++ 03代码不会移动该类,因此没有理由生成移动ctor。
– MSalters
11年8月12日在9:27
评论
并非其所有成员函数都会表现出已定义的行为。只有那些没有先决条件的人。例如,您可能不想pop_back从源移出的向量。但是您当然可以确定它是否为empty()。
– Howard Hinnant
2011年8月11日14:40
@Howard Hinnant:空向量的pop_back无论如何在内存中都具有未定义的行为,因此,我很确定,来自移动的向量的pop_back表现出未定义的行为是一致的。
–小狗
2011年8月11日14:50
我们正在讨论移动对象。没有已知对象处于空状态。移出的对象具有未指定的状态(除非另外指定,否则除外)。 [lib.types.movedfrom]
– Howard Hinnant
2011年8月11日15:11
@Howard未指定,但有效,因此pop_back的行为仍类似于在任何有效向量上(甚至可能是空向量)。
–克里斯蒂安·劳(Christian Rau)
2011年8月11日15:15
在这种情况下,未指定和有效的含义是什么?
– Ankur S
18年6月19日在12:41