【问题标题】:Is it ok to use double pointer output parameters when return value is occupied?返回值被占用时使用双指针输出参数可以吗?
【发布时间】:2017-10-18 13:16:54
【问题描述】:

我正在尝试实现一个简单的 GetOrCreate() 方法 - 按键获取一个对象,或者如果不存在则创建一个新对象。到目前为止,没有任何想法。我还希望我的函数的返回值为Status。所以我创建了以下内容:

Status GetOrCreate(KeyType key, ObjectType* object) {
  Status s = OK;
  decltype(my_map)::iterator iter;
  bool inserted_new;
  std::tie(iter, inserted_new) = clients_.insert(key, ObjectType(...));
  if (inserted_new) {
    // s = ... Initialize the new ObjectType ...
  }
  *object = iter->second;
  return s;
}

并调用函数:

ObjectType result(...);
Status s = GetOrCreate(key, &result);

现在,我觉得有点浪费,因为:

  1. *object = iter->second; 中有不必要的副本
  2. ObjectType result(...) 中有不必要的对象初始化;

(不确定。我可能错了,或者 c++11 忽略了它们。但我还是想明确知道我在做什么)。

所以我创建了一个版本 #2,它通过 ObjectType** object 代替。我不害怕双指针,但可能需要向我的审阅者解释更多。由于project code-style*& 不是一个选项。

似乎是一个非常基本的设计问题,但我摸不着头脑。那么,在这里使用双指针是否合理?有更好的方法吗?

我使用的是 C++11(我的大部分经验是 98)。

【问题讨论】:

  • 有什么理由不能同时返回包含状态和指针的结构体?
  • (1) 使用emplace,砍掉中间人。 (2) 为什么不按照UKMonkey所说的去做呢?甚至可能像标准库那样std::pair<Status, ObjectType>。 (3) 顺便说一句,您确定要退回一份吗?
  • IMO:关于google.github.io/styleguide/cppguide.html#Reference_Arguments - 尝试改变这条规则 - 很好......也许我不会完全说出我的想法......
  • @EladWeiss - 我宁愿不开始关于优雅的辩论。错误状态很少被正确地遵守......所以无论如何。无论如何,只要返回值被占用,您就没有太多选择。也许是boost::optional?这样至少调用者不必默认构造Object(一种反模式)。
  • 如果您现有的方法样式是返回状态,那么当您想要返回更多信息而不是使用指向调用方存储的指针时,您别无选择,但我会将其添加为第三个参数,即是可选的,并且可以是来自调用者的 NULL。但是,状态返回语义的丢失是发明异常的部分原因。 Emplace 可以帮助您在不构造空或副本的情况下将数据导入地图,但您可能需要使用 piecewise_construct 对复杂性才能在不首先构造地图对象的情况下为地图编制索引。

标签: c++ c++11 pointers


【解决方案1】:

如何使用智能指针:

std::pair<Status, std::shared_ptr<ObjectType>> GetOrCreate(KeyType key) {
  Status s = OK;
  decltype(my_map)::iterator iter;
  bool inserted_new;
  std::tie(iter, inserted_new) = clients_.insert(key, ObjectType(...));
  if (inserted_new) {
    // s = ... Initialize the new ObjectType ...
  }
  return std::pair<Status, std::shared_ptr<ObjectType>>(s, iter->second);
}

并像这样使用它:

auto ret = GetOrCreate(key, result);
// ret->first is Status
// ret->second is std::shared_ptr<ObjectType>

【讨论】:

    猜你喜欢
    • 2018-05-30
    • 2013-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 2019-01-26
    • 2010-12-23
    • 2015-06-17
    相关资源
    最近更新 更多