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<>
.
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.
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
. 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. Am I doing something wrong or is this an issue with Boost.Variant? Both examples where attempted using Boost 1.65 and GCC 7.2.0.
The problem is that the move-constructor is not noexcept, which makes it unsuitable:
B(B&&) noexcept {};
You can also write:
B(B&&) = default;
in which case the compiler implicitly generates a noexcept
move constructor.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.