msk*_*her 5 c++ boost optional-variables
我有一个可选的POD结构,它将包含在一个union中.
boost::optional<>按价值保持其类型,所以我认为这可行:
union helper
{
int foo;
struct
{
char basic_info;
struct details {
//...
};
boost::optional<details> extended_info;
} bar;
// ...
};
helper x = make_bar();
if( x.bar.extended_info )
{
// use x.bar.extended_info->elements
}
Run Code Online (Sandbox Code Playgroud)
但VS2008抱怨我的barstruct现在有一个复制构造函数,因为该boost::optional<details>元素.
作为替代,我添加了一个布尔标志来指示可选参数是否有效,但是它很笨重:
union helper
{
int foo;
struct
{
char basic;
struct details {
bool valid;
//...
} extended;
} bar;
// ...
};
Run Code Online (Sandbox Code Playgroud)
我考虑过实现details::operator bool()返回details::valid变量,但这是模糊不清的,也是对人类的伤害.
boost::optional<>清楚地记录语法和意图,不需要侦探工作.
最后,helperunion需要是POD,所以我不能做任何动态分配 - 否则我会使用指针.
对于在语法上与boost::optional<>联盟中可用的东西相似的东西的任何建议?
Öö *_*iib 13
您不能将非POD类型用作union中的字段.在C++中使用boost :: variant或类似的东西而不是union.保留union只是为了与用C编写的模块兼容.
正如其他人提到的,理想的做法是将 a 更改union为 a boost::variant<>。
但是,如果这不可能,您可以实现 POD 近似,boost::optional<>如下所示:
template <typename T>
class Optional
{
T value;
bool valid;
public:
// for the if(var) test
operator bool() const { return valid; }
// for assigning a value
Optional<T> &operator=(T rhs)
{
value = rhs;
valid = true;
return *this;
}
// for assigning "empty"
Optional<T> &operator=(void *)
{
valid = false;
return *this;
}
// non-const accessors
T &operator*() { return value; }
T *operator->() { return &value; }
// const accessors
const T &operator*() const { return value; }
const T *operator->() const { return &value; }
};
Run Code Online (Sandbox Code Playgroud)
如果您持有 的 const 实例,则 const 访问器是必需的Optional<>。
与指针一样,Optional<T>没有默认状态,并且必须在依赖它之前进行初始化(无论是否为空)。
与 不同boost::optional<T>,Optional<T>不能从其值类型构造T,而只能从另一个 构造Optional<T>。
如果您确实想在构造时对其进行值初始化或空初始化,则可以使用operator Optional<T>(). 我选择不这样做。
Optional<details> additional_info;
Optional<details> more_info(additional_info);
Run Code Online (Sandbox Code Playgroud)
// if there's no additional info
additional_info = 0;
// if there is extended info
details x;
// ...populate x...
additional_info = x;
Run Code Online (Sandbox Code Playgroud)
if( extended_info )
{
extended_info->member;
// - or -
details &info = *extended_info;
}
Run Code Online (Sandbox Code Playgroud)
所以——结果并没有太糟糕。它并不让我感到很温暖和模糊,但它完成了工作。
| 归档时间: |
|
| 查看次数: |
994 次 |
| 最近记录: |