5

我正在用 C++ 编写一个简单的容器类,类似于存储由键索引的对象的映射。我想提供一个访问器功能,例如:

V& getValue(const K &key);

我在其中返回对该值的引用。

但我也想处理键/值不存在并能够向用户返回一些状态的情况(可能有一些原因导致我想通过某种状态类型与调用者通信回不存在)。

我想我可以执行以下操作,但调用它需要在调用此函数之前构造一个 V 对象,我只是要将内部 V 对象复制到通过引用传入的对象中,所以这看起来很糟糕.

Status getValue(const K &key, V& v);

我也可以这样做:

V &getValue(const K &key, Status &s);

但是由于某种原因,这似乎有点笨拙,因为焦点从状态中移开,用户可能会忘记检查它(但也许这不是我的问题)。

那么无论如何有没有类似的功能

Status getValue(const K &key, V& v);

在调用它之前不需要构造一个虚拟的 V 对象吗?您不能将引用传递给引用。我想我可以使用指针并且很乐意这样做,但是对于创建一个简单易用和关于函数的推理来说不太理想。

有什么想法吗?

4

7 回答 7

2

您可以使用原始函数V& getValue(const K &key),并引发异常以指示不成功的Status值。

然后,调用者可以选择延迟他们处理问题的方式(通过让异常冒泡到适当的处理程序),但他们不能完全忘记它,因为否则程序会崩溃。呼叫站点不必堆满状态检查和错误报告代码。

于 2012-08-15T14:35:13.400 回答
2

通常的解决方案是提供一个bool contains(const K &key)函数,如果您不希望访问器静默创建条目,请让它抛出异常。(有两个访问器,一个抛出异常,另一个创建条目也很常见)

当然,这可能不是你想要的。您想将所有这些都放入一个函数中的原因是什么?

于 2012-08-15T14:25:44.020 回答
1

boost::optional如果您不想使用 boost,我会使用或创建一个类似的模板。使用boost::optional您的功能将如下所示:

boost::optional<MyClass &> getValue(const K &key)
于 2012-08-15T14:19:34.303 回答
1

我看到 3 个选项:

  1. 返回一个可以转换为 V& 的“包装器”对象,并且可以判断它是否存储了有效的引用(可以围绕 V* 实现)。
  2. 返回一个指针。
  3. 如果未找到密钥,则返回引用并抛出异常。

我个人会带一个指针。

于 2012-08-15T14:25:09.173 回答
0

First I'll answer your question as written: I would suggest returning a boost::optional<boost::ref<V> > so that you can still return by reference, but optionally so.

However, I wouldn't suggest this interface. The standard containers already have an interface that solves this exactly problem, namely returning iterators rather than values. I would suggest just using an "iterator" interface (it doesn't have to be a real full-blown iterator) and returning an end/one past the end to indicate that the iter is not found, rather than returning by reference or not. The more you make your container's interface look like a standard container, the greater your options for using standard algorithms AND plugging it in anywhere you want as a substitution.

于 2012-08-15T14:58:17.823 回答
0

考虑返回boost::variant<V &, Status>or (equivalently) boost::variant<std::reference_wrapper<V>, Status>

于 2012-08-15T14:22:53.977 回答
0

我会遵循 std::map 接口的一个想法:

std::pair<iterator,bool> getValue(const K& key);

值对象可通过迭代器访问,bool标志显示该值是否存在。

于 2012-08-15T14:25:49.123 回答