从函数返回空std :: pair

问题描述 投票:4回答:5

是否可以从函数返回空对?意思是,遵循函数原型的规则,但是对中没有任何元素(例如NULL)。理解一对只是存在,所以我不知道这在概念上是否可行。如果有意义的话,我需要返回一个NULL或空的对。

例如,

pair<int, int> MyClass::someFunction()
{

   // do something that means we need to return an empty pair
   return NULL; // <--- this does not work obviously
}

不幸的是,对我来说不可能提升。

c++ std-pair
5个回答
6
投票

一般来说,空对甚至没有意义。毕竟,pair是一个包含两个对象的容器。

然而,您可以使用Boost.Optional制作类似空对的东西。然后你要么使用boost::optional<std::pair<...>>,你可以选择返回一对或空状态,或者使用std::pair<boost::optional<...>, boost::optional<...>>作为一对,其中任何一个对象都可以为空。


3
投票

你可以返回指针......或者使用boost::optional<T>。可选将更好......

boost::optional<std::pair<int, int> > MyClass::someFunction()
{
    return boost::optional<std::pair<int, int> >();
}

void f(const MyClass& f)
{
    boost::optional<std::pair<int, int> > ret = f.someFunction();
    if (!ret) // empty
    {
        ...
    }
}

3
投票

通过考虑C ++编译器在这种情况下生成代码的方式,可以很容易地解释您的问题的答案。

std::pair<int, int>按价值返还。

由于MyClass::someFunction()按值返回对象,因此事件序列如下:

  • 调用函数为堆栈中的std::pair<int, int>保留空间
  • MyClass::someFunction()被称为
  • return语句的右侧是对早先在堆栈上保留的位置的赋值。有一个隐含的std::pair<int, int>建设发生。

因此返回NULL指针是不可能的。


3
投票

创建自己的“可选对”(类似于boost::optional<std::pair<…>>,但具有不同的接口)并不需要太多,例如:

template <typename T1, typename T2> struct OptPair : std::pair<T1, T2>
{
  typedef std::pair<T1, T2> base_t;
  bool contains;
  OptPair() : contains(true) {}
  explicit OptPair(bool x) : contains(x) {}
  OptPair(const T1& x, const T2& y) : base_t(x, y), contains(true) {}
  template <class U, class V>
  OptPair(const std::pair<U,V> &p) : base_t(p), contains(true) {}
  template <class U, class V> OptPair(const OptPair<U,V> &p) : base_t(p), contains(p.contains) {}
  // No need to define operator=, as the default will construct an OptPair<T1, T2>
  // if necessary, then copy members into *this.
};

template <typename T1, typename T2>
OptPair<T1, T2> makeOptPair() { return OptPair<T1, T2>(); }

template <typename T1, typename T2>
OptPair<T1, T2> makeOptPair(const T1 &x, const T2 &y) {
  OptPair<T1, T2> p(true);
  p.first = x;
  p.second = y;
  return p;
}

template <typename OS, typename T1, typename T2>
OS &operator<<(OS &os, const OptPair<T1, T2>& p) {
  os << "<OptPair: ";
  if (p.contains) os << p.first << ", " << p.second;
  else os << "empty";
  os << ">";
  return os;
}

然后你可以像std :: pair一样使用它(甚至可以与std :: pair交替使用它,来回分配值),但是增加了传递“空”值的能力,如下所示:

OptPair<int, int> someFunction()
{
   ...
   return OptPair<int, int>(false); 
}

您必须确保在使用之前检查结果,如下所示:

void doStuffWithPair(std::pair<int, int>);
void doStuffWithEmpty();
...
OptPair<int, int> ret = someFunction();
if (ret.contains) doStuffWithPair(ret);
else doStuffWithEmpty();

1
投票

根据定义,一对有2个元素。它不能没有。

你需要像boost::optional<std::pair<T1,T2>>这样的东西。然后你可以选择是否有一对。你可以找到boost :: optional here的文档。

© www.soinside.com 2019 - 2024. All rights reserved.