我有一个getter对象,它返回一个Type类型的对象,定义如下:
typedef boost::variant<int, std::string> Empty;
通常情况下,我既没有返回int也没有返回字符串,而是必须返回空状态。你觉得我怎么回到这个州?
a)typedef一个Empty类型并将其添加到变体:boost::variant<int, std::string, Empty>
。
b)返回Type()
c)施放异常
d)返回一个boost :: shared_ptr,在空的情况下指向NULL。
答案 0 :(得分:8)
正确的答案是使用boost::blank
来表示其中没有任何内容的变体。因此,您的变体typedef如下所示:
typedef boost::variant<boost::blank, int, std::string> Empty;
blank
专为此设计,variant
具有基于它的特殊代码。通过使用它,您可以在复制时获得无内存分配保证(如果成员不在副本上分配)。这很好。
由于您的变体可能是“空的”,因此所有处理访问者都可以处理它。添加额外的访问者路径通常比基于optional
或其他内容的多个条件更方便。不同的代码路径将本地化为访问者,这通常比optional<variant>
更有意义。
答案 1 :(得分:3)
将其包裹在boost::optional
中,这有一个简单的测试(可转换为布尔值)以确定是否分配了有效值 - 然后您不需要以“空”状态污染您的变体。 e.g。
boost::optional<boost::variant<... > > some_func()
{
:
}
当你真正需要归还某些东西时,请记住在你的函数中使用原位构造。
答案 2 :(得分:1)
如果方法有可能无法返回对象,这是一种常见的方法 - 让方法返回bool:
bool get_value(Type& type) {
if ( /*check variant emptyness*/) // one can use this - http://stackoverflow.com/a/7668530/670719
return false;
// else assign type
}
对您的解决方案的评论:
a)如果你将返回Empty,你仍然需要在方法调用后进行检查。那么为什么在已经有内置bool的情况下添加更多类型呢。
b)Type()可以与合法变量
具有相同的值c)异常是针对特殊情况的,但是从您的描述中“通常是”
d)你的问题是你不能使用Type并且同时不能返回boost :: variant,所以在没有解决初始问题的情况下,添加一个带有额外所有权问题的类型会带来更多问题干净的界面。