4

我有一个 getter 对象,它返回一个 Type 类型的对象,定义如下:

typedef boost::variant<int, std::string> Empty;

通常情况下,我既没有要返回的 int 也没有要返回的字符串,而是必须返回一个空状态。你认为我如何恢复这种状态?

a) typedef 一个空类型并将其添加到变体中:boost::variant<int, std::string, Empty>.

b)返回类型()

c) 抛出异常

d) 返回一个 boost::shared_ptr,它在为空的情况下指向 NULL。

4

3 回答 3

8

正确的答案是boost::blank用于其中可以没有任何内容的变体。因此,您的变体 typedef 如下所示:

typedef boost::variant<boost::blank, int, std::string> Empty;

blank是专门为此设计的,并variant有基于它的特殊代码。通过使用它,您可以在复制时获得无内存分配保证(如果成员未在复制时分配)。所以这很好。

由于您的变体可以是“空的”,因此您的所有处理访问者都可以处理它是很重要的。添加额外的访问者路径通常比基于某个optional或某事的多个条件更方便。不同的代码路径将本地化给访问者,这通常比optional<variant>.

于 2012-10-08T07:55:57.070 回答
3

将它包装在 a 中boost::optional,这有一个简单的测试(可转换为布尔值)来确定是否分配了有效值 - 那么您不需要用“空”状态污染您的变体。例如

boost::optional<boost::variant<... > > some_func()
{
:
}

当您实际需要返回某些内容时,请记住在您的函数中使用就地构造。

于 2012-10-08T07:00:14.053 回答
1

如果方法可能无法返回对象,这是一种常见的方法 - 使方法返回布尔值:

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,您仍然需要在方法调用后进行检查。那么,如果已经有内置的布尔值,为什么还要添加更多类型。

b) Type() 可以具有与合法变量相同的值

c)例外是针对特殊情况,但根据您的描述“通常是”

d) 你的问题是你不能使用 Type 并且同时不能返回 boost::variant,所以添加一个带有额外所有权问题的类型会带来更多的问题,而不解决最初的清洁界面问题.

于 2012-10-08T06:33:28.417 回答