简体   繁体   English

boost :: variant处理仅移动类型的奇怪行为

[英]Strange behavior in boost::variant's handling of move-only types

Given the following: 鉴于以下内容:

#if __cplusplus >= 201703L
    #include <variant>
    using std::variant;
#else
    #include <boost/variant.hpp>
    using boost::variant;
#endif

Consider this snippet. 考虑一下这个片段。 This compiles under both c++17's std::variant<> and boost::variant<> . 这在c ++ 17的std::variant<>boost::variant<>下编译。

struct B
{
    B() = default;
    B(const B&) = delete;
    B(B&&) {}
    B& operator=(const B&&) = delete;
    B& operator=(B&&) {}
};

int main()
{
    variant<B, int> v;
    v = B{};
}

However, this other example only compiles with C++17's std::variant<> , since boost::variant<> attempts to perform a copy-assignment. 但是,这个其他示例仅使用C ++ 17的std::variant<>编译,因为boost::variant<>尝试执行复制赋值。

struct A
{
    A(int) {}
};

struct B
{
    B(int) {}
    B(const B&) = delete;
    B(B&&) {}
    B& operator=(const B&) = delete;
    B& operator=(B&&) {}
};

int main()
{
    variant<A, B> v{A{42}};
    v = B{42}; // This line doesn't compile with Boost
}

The only notable differences between the two examples are the presence of struct A and default constructors versus constructors taking an int . 的两个例子之间的唯一显着的差异是存在struct A和默认构造与服用构造int I have also found out that if the move constructor and assignment operator of class B in the second case are = default ed, it can be compiled using Boost. 我还发现,如果第二种情况下class B的移动构造函数和赋值运算符是= default ed,则可以使用Boost进行编译。 Am I doing something wrong or is this an issue with Boost.Variant? 我做错了什么,或者这是Boost.Variant的问题? Both examples where attempted using Boost 1.65 and GCC 7.2.0. 尝试使用Boost 1.65和GCC 7.2.0的两个示例。

The problem is that the move-constructor is not noexcept, which makes it unsuitable: 问题是move-constructor不是noexcept,这使得它不合适:

https://godbolt.org/g/368cjJ https://godbolt.org/g/368cjJ

B(B&&) noexcept {};

You can also write: 你也可以写:

B(B&&) = default;

in which case the compiler implicitly generates a noexcept move constructor. 在这种情况下,编译器隐式生成noexcept移动构造函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 处理包含只移动类型的变体 - dealing with variants containing move-only types 如何欺骗boost :: asio以允许只移动处理程序 - How to trick boost::asio to allow move-only handlers 将仅移动 function arguments 传递给 boost::thread 构造函数 - Passing move-only function arguments to boost::thread constructor 在成员容器中使用仅移动但可克隆类型的复制构造函数 - Copy constructors with move-only, but cloneable types in member containers 为什么 extern 模板实例化不适用于仅移动类型? - Why does extern template instantiation not work on move-only types? std :: move_if_noexcept的基本原理仍在移动投掷仅移动类型? - Rationale for std::move_if_noexcept still moving throwing move-only types? boost multi_index-如果元素的类型为仅移动,如何将元素从一个容器添加到另一个容器? - boost multi_index - how to add an element from one container to another if its type is move-only? 如何通过值传递仅移动类型(例如std :: unique_ptr)? - How is it possible to pass move-only types (e.g. std::unique_ptr) by value? VS2010绑定实现不支持只移动类型? - VS2010 bind implementation doesn't support move-only types? std::bind 是否适用于一般只移动类型,特别是 std::unique_ptr ? - Does std::bind work with move-only types in general, and std::unique_ptr in particular?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM