gpt4 book ai didi

c++ - 是否保证 std::swap(x, x) 保持 x 不变?

转载 作者:IT老高 更新时间:2023-10-28 21:48:19 25 4
gpt4 key购买 nike

这个问题是基于下面的讨论 recent blog post by Scott Meyers .

在 C++98 和 C++11 中 std::swap(x, x) 应该使 x 保持不变,这似乎是“显而易见的”,但我在这两个标准中都找不到任何保证。 C++98 定义 std::swap 在复制构造和复制赋值方面,而 C++11 在移动构造和移动赋值方面定义它,这似乎是相关的,因为在 C+ +11(和 C++14),17.6.4.9 说移动赋值不必是自赋值安全的:

If a function argument binds to an rvalue reference parameter, the implementation may assume that this parameter is a unique reference to this argument. ... [ Note: If a program casts an lvalue to an xvalue while passing that lvalue to a library function (e.g. by calling the function with the argument move(x)), the program is effectively asking that function to treat that lvalue as a temporary. The implementation is free to optimize away aliasing checks which might be needed if the argument was an lvalue. —end note ]

defect report产生这种措辞的原因清楚地表明了后果:

this clarifies that move assignment operators need not perform the traditional if (this != &rhs) test commonly found (and needed) in copy assignment operators.

但是在C++11和C++14中,std::swap预计会使用这个实现,

template<typename T>
void swap(T& lhs, T& rhs)
{
auto temp(std::move(lhs));
lhs = std::move(rhs);
rhs = std::move(temp);
}

第一个赋值是对 self 进行赋值,其中参数是一个右值。如果 T 的移动赋值运算符遵循标准库的策略并且不担心赋值给 self,这似乎会导致未定义的行为,这意味着 std::swap(x, x) 也会有 UB。

即使在孤立的情况下也令人担忧,但如果我们假设 std::swap(x, x) 在 C++98 中应该是安全的,这也意味着 C++11/14 的 std::swap 可以默默地破坏 C++98 代码。

那么 std::swap(x, x) 是否保证保持 x 不变?在 C++98 中?在 C++11 中?如果是,这与 17.6.4.9 的移动分配权限不是自分配安全的相互作用如何?

最佳答案

我相信,至少在 C++20(a) 中,[utility.requirements] 部分可能会涵盖这一点,该部分指出:

15.5.3.2 describes the requirements on swappable types and swappable expressions.

引用的部分,[swappable.requirements],进一步说明(我在最后两个要点中强调):

An object t is swappable with an object u if and only if:

  • the expressions swap(t, u) and swap(u, t) are valid when evaluated in the context described below; and
  • these expressions have the following effects:
    • the object referred to by t has the value originally held by u; and
    • the object referred to by u has the value originally held by t.

在我看来,如果自交换以某种方式损坏了内容,那些粗体部分将失效,这意味着它们不会是可交换的。

同一部分后来也指出:

An rvalue or lvalue t is swappable if and only if t is swappable with any rvalue or lvalue, respectively, of type T.

那里没有关于自交换的胡扯,它清楚地声明了任何右值或左值(分别),包括它自己。


(a) 这两个约束也存在于 C++17、c++14 和 C++11 中,任何比这更早的东西,我都不在乎 :-)

关于c++ - 是否保证 std::swap(x, x) 保持 x 不变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24444630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com