boost::变体对仅移动类型的处理中的奇怪行为
Strange behavior in boost::variant's handling of move-only types
给定以下情况:
#if __cplusplus >= 201703L
#include <variant>
using std::variant;
#else
#include <boost/variant.hpp>
using boost::variant;
#endif
考虑这个片段。这在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{};
}
但是,另一个示例仅使用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
ED,则可以使用Boost进行编译。我是做错了什么还是这是boost.variant的问题?尝试使用Boost 1.65和GCC 7.2.0的两个示例。
问题是move-constructor并不是不适合的,这使其不合适:
https://godbolt.org/g/368cjj
B(B&&) noexcept {};
您也可以写:
B(B&&) = default;
在这种情况下,编译器隐式生成noexcept
移动构造函数。
相关文章:
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 为什么 GCC 在使用类型别名时处理 const reinterpret_cast不同?
- 像union_这样的 Boost.Geometry 操作如何处理浮点类型的基本不精确性?
- 模板函数如何处理可能共享一个交集的多个类型名称?
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 如何处理模板类中的复合类型
- C++在一个映射中存储不同的指针类型(并处理销毁)
- 如何在C库中处理与C++不同大小的类型
- 如何处理具有无效数据类型的异常
- 处理一般情况混合类型和非类型的可变参数模板
- 类型不可知的抽象以使用相同的运行时接口处理正向和反向迭代器和范围?
- 如何在Boost::program_options配置文件中为非字符串的自定义选项值类型处理空格
- 我可以让返回类型自动处理具有相同签名但捕获不同内容的 lambda 吗?
- 如何处理高于 7FF.. 64 位和uint64_t类型的十六进制值
- 处理类型结构数组
- 我应该如何处理类型而不是方法的多重继承冲突
- 如何在SQLite中处理Blob时处理类型错误
- 如何重写模板化函数来处理类型推断