我正在尝试使用c ++ 11功能实现boost :: optional之类的数据结构。以下是我到目前为止的情况:
template<typename T>
struct maybe {
bool valid;
union {
T value;
};
maybe() : valid(false) {}
maybe(const T& _v) {
valid = true;
new (&value) T(_v);
}
maybe(const maybe& other) {
if (other.valid) {
valid = true;
new (&value) T(other.value);
}
else valid = false;
}
~maybe() {
if (valid)
value.~T();
}
bool is_valid() { return valid; }
operator T&() {
if (valid) return value;
throw std::bad_exception();
}
};
我利用无限制联合功能为可选值创建一个正确对齐的空间,该空间可以原位存储,而不是动态分配空间。事情主要起作用,除非我想创建一个可能&lt;&gt;有参考。例如maybe<int&>
导致g ++ 4.7抱怨:
error: ‘maybe<int&>::<anonymous union>::value’ may not have reference type ‘int&’
because it is a member of a union
我应该怎么做才能进行类商店推荐?我们也欢迎任何其他改进/建议。
答案 0 :(得分:8)
为了使这个工作与引用一起使用你肯定需要一个显式的特化,因为你不能做一个新的引用:你需要使用指针进行存储。
除此之外,代码缺少复制赋值运算符。移动构造函数和移动赋值运算符也很不错(特别是因为这是重新实现{1}}的首要原因:boost中的那个缺少它们。)
答案 1 :(得分:3)
为C ++ 14提出了可选类型,但是由于标准中未定义行为的一些极端情况,它被推迟到C ++ 17。
幸运的是,UB问题对大多数人来说并不重要,因为所有主要的编译器都能正确定义它。因此,除非您使用旧的编译器,否则您实际上可以直接插入可用于在项目中实现可选类型的代码(它只是一个头文件):
https://raw.githubusercontent.com/akrzemi1/Optional/master/optional.hpp
然后你可以像这样使用它:
#if (defined __cplusplus) && (__cplusplus >= 201700L)
#include <optional>
#else
#include "optional.hpp"
#endif
#include <iostream>
#if (defined __cplusplus) && (__cplusplus >= 201700L)
using std::optional;
#else
using std::experimental::optional;
#endif
int main()
{
optional<int> o1, // empty
o2 = 1, // init from rvalue
o3 = o2; // copy-constructor
if (!o1) {
cout << "o1 has no value";
}
std::cout << *o2 << ' ' << *o3 << ' ' << *o4 << '\n';
}