繁体   English   中英

我应该使用什么函数签名来返回对可能不存在的对象的引用?

[英]What function signature should I use to return a reference to an object that might not exist?

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

V& getValue(const K &key);

在这里我返回对值的引用

但是我还想处理键/值不存在并且能够向用户返回某些状态的情况(可能由于某些原因,我不希望通过某种状态类型与主叫方进行通讯) )。

我想我可以做下面的事情,但是调用它需要在调用该函数之前构造一个V对象,并且我只是将内部V对象复制到通过引用传递的那个V对象中,所以这似乎很糟糕。

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

我也可以这样做:

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

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

所以无论如何都有类似的功能

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

不需要在调用之前构造伪V对象? 您不能将参考传递给参考。 我想我可以使用指针,并且很高兴这样做,但是创建一个简单易用的函数并提出其理由并不那么理想。

有什么想法吗?

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

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

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

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

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

boost::optional<MyClass &> getValue(const K &key)

我看到3个选项:

  1. 返回一个“包装器”对象,该对象可以转换为V&并可以告诉它是否存储有效的引用(可以在V *周围实现)。
  2. 返回一个指针。
  3. 如果找不到该键,则返回引用并抛出异常。

我个人会带一个指针。

考虑返回boost::variant<V &, Status>或(等效地) boost::variant<std::reference_wrapper<V>, Status>

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

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

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

首先,我将以书面形式回答您的问题:我建议您返回boost::optional<boost::ref<V> >以便您仍然可以按引用返回,但是可以选择这样返回。

但是,我不建议使用此界面。 标准容器已经具有解决此问题的接口,即返回迭代器而不是值。 我建议仅使用“迭代器”界面(它不一定是真正的成熟迭代器),并在end返回一个end /一个以指示未找到该迭代器,而不是通过引用或不返回。 您使容器的界面看起来像标准容器的次数越多,使用标准算法并将其插入到您想要替代的任何位置的选择就越多。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM