[英]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.