传递可选对象而不复制它

Pass optional object without copying it

我在重构旧代码时遇到了以下情况:

// pointers to const are discouraged in our code base
void Do(Foo* exists, Foo* maybe_null) {
  // does not change *exists or *maybe_null
}

int main() {
  // ...
  Do(&foos[i], test_both ? &bars[i] : nullptr);
  // ...
  HighOrderFunction(foos, bars, &Do);
  // ...
}

因此,Do 是用两个 Foo 对象调用的,其中一个肯定存在而第二个可能不存在,这取决于一些外部测试。我尝试解决的当前代码存在的问题:

到目前为止,我想出了三个可能的解决方案,none 其中我完全满意:

那么,有什么 better/cleaner 我可以在这种情况下使用的解决方案吗?

(我正在使用 C++11 和一些 std 添加,例如可选)

使 Do 成为仿函数,而不仅仅是函数。

 struct Do
 {
      void operator()(const Foo &must_be_provided);
      void operator()(const Foo &must_be_provided, const Foo &maybe_unneeded);
 };

然后,在实现了Do::operator()

的两种形式之后
 void some_function(Do f)
 {
       // assume access to foos and bars here
     if (test_both)   // assume determined at run time
         f(foos[i]);
     else
        f(foos[i], bars[i]);
 }

请注意,仿函数可以按值传递、按引用传递,或者可以在指针中传递其地址(尽管调用函数的语法稍有变化)。

如果你想要一个可选的引用,你可以使用std::reference_wrapper<Foo>:

Do(const Foo&, optional<std::reference_wrapper<const Foo>>)

这将避免复制您的对象。并将使函数正式接受引用。

当然创建了一个 reference_wrapper 对象。但它相当轻。大多数实现只是屏蔽一个指针。