【问题标题】:Is it possible to move a boost::optional?是否可以移动 boost::optional ?
【发布时间】:2012-06-02 17:55:02
【问题描述】:

我一直在尝试在具有boost::optional 成员变量的类中定义默认的移动构造函数。

#include <boost/optional.hpp>
#include <utility>
#include <vector>

struct bar {std::vector<int> vec;};

struct foo {
  foo() = default;
  foo(foo&&) = default;
  boost::optional<bar> hello;
};

int main() {
  foo a;
  foo b(std::move(a));
}

我的编译器同时支持移动语义和默认的移动构造函数,但我无法让它工作。

% clang++ foo.cc -std=c++11 -stdlib=libc++
foo.cc:15:7: error: call to deleted constructor of 'foo'
  foo b(std::move(a));
      ^ ~~~~~~~~~~~~
foo.cc:9:3: note: function has been explicitly marked deleted here
  foo(foo&&) = default;
  ^
1 error generated.

有没有办法在不修改 Boost 源代码的情况下移动 boost::optional?还是应该等到 Boost 支持移动?

我过去在boost::any 上遇到过同样的问题。

【问题讨论】:

标签: c++ boost c++11 move-semantics boost-optional


【解决方案1】:

Boost.Optional 仅从 Boost 版本 1.56 开始支持移动构造。见the release notes

【讨论】:

    【解决方案2】:

    查看boost::optional 源代码,它没有定义移动构造函数或移动赋值。但是,它确实定义了复制构造函数和赋值,这会阻止编译器为其自动生成移动构造函数和赋值。

    Move constructor — Q&A:

    编译器将隐式生成移动构造函数作为成员移动,除非您明确定义了复制构造函数或复制/移动赋值或析构函数

    正如 Luc Danton 所暗示的,需要有一种治疗方法。让我们尝试使用swap 移动boost::optional,希望创建一个空的boost::optional 很便宜,然后我们只需将默认构造的boost::optional 与来自r 值foo 的@交换,例如:

    foo(foo&& b) {
        hello.swap(b.hello);
    }
    

    移动分配也是如此。

    【讨论】:

    • 这是一个正确的诊断,但你需要治愈才能完成这个答案!
    • 嗯,这很不幸。我可以编写一个支持使用std::swap 移动的包装类,并隐式转换为boost::optional。我希望这将在下一个版本的 Boost 中得到修复。
    【解决方案3】:

    目前尚不清楚 C++11 特性对 boost::optional 的支持有多重要。

    我在 Internet 上找到了一个很好的人,他在 boost 许可证下给了我一些他自己的代码......仍在进行一些调整。它正处于对我有用的地步。也许它会帮助任何看到这个问题的人:

    https://github.com/hostilefork/CopyMoveConstrainedOptional

    还有一个更大的团队努力定义std::optional,这一直在进行......但他们的参考实现无法处理我遇到的一些情况:

    http://kojot.sggw.waw.pl/~akrzemi1/optional/tr2.optional.proposal.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-23
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-20
      相关资源
      最近更新 更多