鉴于以下内容:
#if __cplusplus >= 201703L
#include <variant>
using std::variant;
#else
#include <boost/variant.hpp>
using boost::variant;
#endif
考虑这个片段。这在c ++ 17&{39} 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{};
}
但是,这个其他示例仅使用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
}
两个示例之间唯一值得注意的差异是struct A
和默认构造函数与构造函数的int
的存在。我还发现,如果第二种情况下class B
的移动构造函数和赋值运算符为= default
,则可以使用Boost进行编译。我做错了什么,或者这是Boost.Variant的问题?这两个例子都试图使用Boost 1.65和GCC 7.2.0。
答案 0 :(得分:5)
问题是move-constructor不是noexcept,这使得它不合适:
B(B&&) noexcept {};
你也可以写:
B(B&&) = default;
在这种情况下,编译器隐式生成noexcept
移动构造函数。