C++ 传递可选对象而不复制它

C++ 传递可选对象而不复制它,c++,c++11,pointers,optional,C++,C++11,Pointers,Optional,我在重构旧代码时遇到以下情况: // 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); // ... High

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

// 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
对象调用,其中一个对象肯定存在,而第二个对象可能不存在,这取决于一些外部测试。我试图解决的当前代码中存在的问题:

  • 第一个参数永远不会为null,因此永远不会使用其指针属性

  • 我通常不喜欢使用null作为空值

到目前为止,我提出了三种可能的解决方案,其中没有一种我完全满意:

  • Do(const Foo&,Foo*)
    :第二个参数的问题与以前相同,现在调用语法不再统一(
    foos[i]
    &bar[i]
    ),这可能会让读者感到困惑

  • Do(const Foo&,const optional&)
    :必须复制第二个
    Foo
    对象来构造可选对象

  • Do(const Foo&,optional)
    :实际上不起作用,因为引用类型的optional是不允许的

  • Do(const-Foo&)
    Do(const-Foo&,const-Foo&)
    重载:当我需要将Do作为函数指针传递时会导致问题

那么,在这种情况下,我有没有更好/更清洁的解决方案


(我正在使用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()
之后


请注意,函子可以通过值、引用传递,也可以通过指针传递其地址(尽管调用函数的语法略有变化)。

Make
Do
函子,而不仅仅是函数

 struct Do
 {
      void operator()(const Foo &must_be_provided);
      void operator()(const Foo &must_be_provided, const Foo &maybe_unneeded);
 };
然后,在实现了两种形式的
Do::operator()
之后


请注意,函子可以通过值、引用传递,也可以通过指针传递其地址(尽管调用函数的语法有一些变化)。

如果需要可选引用,可以使用
std::reference\u包装器

Do(常量Foo&,可选)
这样可以避免复制对象。并将使函数正式接受引用


确保创建了一个
reference\u包装
对象。但它相当轻。大多数实现只是屏蔽一个指针。

如果您想要一个可选的引用,可以使用
std::reference\u wrapper

Do(常量Foo&,可选)
这样可以避免复制对象。并将使函数正式接受引用


确保创建了一个
reference\u包装
对象。但它相当轻。大多数实现只是屏蔽一个指针。

对于
voiddo(const-Foo&)
voiddo(const-Foo&,const-Foo&)
来说,重载都是一个运行时值还是一个编译时值?@非常感谢您的评论。我忘了提到Do的指针需要时不时地传递给高阶函数,所以重载不是一个选项。很抱歉造成混淆,我已将该信息添加到我的问题中。@skypjack这是一个运行时值。@AndreasT
HighOrderFunction
是如何定义的?重载确实仍然是一个可行的解决方案。
voiddo(const-Foo&)
voiddo(const-Foo&,const-Foo&)
的重载都是运行时值还是编译时值?@非常感谢您的评论。我忘了提到Do的指针需要时不时地传递给高阶函数,所以重载不是一个选项。很抱歉造成混淆,我已将该信息添加到我的问题中。@skypjack这是一个运行时值。@AndreasT
HighOrderFunction
是如何定义的?重载确实仍然是一个可行的解决方案。谢谢,这可能是我的想法的最好执行,使用可选的。我仍然将另一个答案标记为已接受,因为它为我遇到的一般问题提供了一个更干净的解决方案。谢谢,这可能是我使用可选答案的想法的最佳执行。我仍然将另一个答案标记为已接受,因为它为我遇到的一般问题提供了一个更干净的解决方案。
Do(const Foo&, optional<std::reference_wrapper<const Foo>>)