【问题标题】:std::swap for non copiable but movable structstd::swap 用于不可复制但可移动的结构
【发布时间】:2014-05-01 20:52:00
【问题描述】:

根据C++ referencestd::swap相当于

T c(std::move(a)); a=std::move(b); b=std::move(c);

这应该允许交换两个不可复制但可移动的对象。所以我不明白为什么

#include<utility>

struct Foo {
  Foo() = delete;
  Foo(int) {};
  Foo(Foo &) = delete;
  Foo(Foo &&) {};
  ~Foo() {};
};

int main() {
  Foo a(1),b(2);
  std::swap(a,b);
}

被编译器拒绝

In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
                 from /usr/include/c++/4.8/utility:70,
                 from swap.cpp:1:
/usr/include/c++/4.8/bits/move.h: In instantiation of ‘void std::swap(_Tp&, _Tp&) [with _Tp = Foo]’:
swap.cpp:13:16:   required from here
/usr/include/c++/4.8/bits/move.h:176:11: error: use of deleted function ‘Foo& Foo::operator=(const Foo&)’
       __a = _GLIBCXX_MOVE(__b);
           ^
swap.cpp:3:8: note: ‘Foo& Foo::operator=(const Foo&)’ is implicitly declared as deleted because ‘Foo’ declares a move constructor or move assignment operator
 struct Foo {
        ^
In file included from /usr/include/c++/4.8/bits/stl_pair.h:59:0,
                 from /usr/include/c++/4.8/utility:70,
                 from swap.cpp:1:
/usr/include/c++/4.8/bits/move.h:177:11: error: use of deleted function ‘Foo& Foo::operator=(const Foo&)’
       __b = _GLIBCXX_MOVE(__tmp);

注意:这适用于 GCC 4.8 和 4.9,但也会发出 clang 抱怨。

【问题讨论】:

  • 通过将Foo(Foo &amp;)声明为=delete,复制赋值运算符也是=delete,因此a=std::move(b);会报错。
  • 这是故意的。我不希望我的课程被复制。

标签: c++ c++11 move swap


【解决方案1】:

您声明了一个移动构造函数。但是,对于std::swap,您需要一个移动赋值运算符。您应该添加以下两个运算符:

auto operator=(const Foo& rhs) & -> Foo& = delete;
auto operator=(Foo&& rhs) & noexcept -> Foo&
{
    // ...
    return *this;
}

【讨论】:

  • +1,但不需要添加复制分配操作 - 当一个类有移动分配操作时,如果不是用户提供的,复制一个被定义为删除。此外,让移动操作不抛出可能是个好主意。
  • 你是不是忘记了某处的双 &&。这些都把我当作普通的赋值运算符?
  • 好的!我现在知道了。我虽然移动分配是从移动构造函数自动生成的。
  • @hivert:如果你仔细想想,那是不可能的。当您进行分配时,目标对象可能正在管理一些需要在从移出对象获取资源之前需要清理的资源。移动构造函数无法处理(也不需要)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 2014-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多