【问题标题】:C++ A function that can return one of two types depending on the accepted valueC++ 可以根据接受的值返回两种类型之一的函数
【发布时间】:2019-12-31 17:50:52
【问题描述】:
fun(int a) {
    if (a) return a; return "empty";
}

我需要一个函数来获取一个数字并根据它返回的数字返回一个 int 变量或一个字符串。 请告诉我如何实现这样的功能。

【问题讨论】:

  • 您必须指定一个返回类型,因此您可以指定一个可以表示多种类型的类型,并可以尝试研究type erasure
  • 这是一个不寻常的要求,但您可以返回这两种类型的联合,或者,对于最新版本的 C++,使用 std::variant
  • 你会如何使用它?
  • 你不能。因为函数声明应该在编译时指定它的返回类型。

标签: c++ function


【解决方案1】:

在 C++ 17 中,您可以使用 variant:

std::variant<int, std::string> fun(int a) {
  if (a) return a; return "empty";
}

或者使用带有optional的结构:

struct r {
  std::optional<int> i;
  std::optional<std::string> s;
};

r fun(int a) {
  r out;
  if (a) out.i = a; else out.s = "empty";
  return out;
}

或者对于以前的标准,使用带有指示有效性字段的结构。

struct r {
  enum class type {i, s};
  int i;
  std::string s;
  type t;
};

r fun(int a) {
  r out;
  if (a) {
    out.i = a;
    out.t = r::type::i;
  else {
    out.s = "empty";
    out.t = r::type::s;
  }
  return out;
}

【讨论】:

    【解决方案2】:

    像 python 这样的可解释语言对参数类型和返回值类型没有限制。但是,C++ 只能接受和返回预定义类型的值。 现在,添加其他答案,如果您没有 C++17,您可以这样尝试:

    std::pair<int, string> func(int a)
    {
       if(a) return std::make_pair(a , "");
       return std::make_pair(0,"string");    
    }
    

    在被调用者中,您可以针对 std::pair 的两个成员检查非空值。

    【讨论】:

      【解决方案3】:

      您可以在例外情况下完成此流程!例如,如果 func 期望使用大于 5 的数字,您可以执行以下操作:

      int func(int a) {
          if (a > 5) { return a; }
          throw std::runtime_error("Empty");
      }
      
      int main() {
          try {
              int x = func(3);
              // Do some stuff with x...
          } catch(const std::exception &e) {
              std::cout << "Looks like the num is " << e.what();
          }
      }
      

      因此,如果事情进展顺利,您要么处理int,要么,如果发生了不好的事情,您从异常中获取字符串并进行处理。

      【讨论】:

      • 我没有看到任何返回 "empty" 的内容。这个答案是猜测返回字符串应该与错误传播有关,但问题并没有要求。
      • @Pete 异常不必用于错误传播,尽管我猜我的字符串没有帮助。我已经编辑过试图摆脱这种情况。 OP 想要一个检查输入并在检查通过时对输入进行操作的函数。否则,他们希望将字符串传播回调用者。对我来说,这听起来像是对异常的完美使用。
      • 虽然“异常不必用于错误传播”在技术上是正确的,但它们施加的开销意味着它们实际上仅用于错误传播。这就是它们的设计目的;它们并非旨在成为替代退货机制。
      【解决方案4】:

      您可以通过将两个不同的任务拆分为单独的函数并从那里继续执行来完成此操作。

      #include <iostream>
      using namespace std;int inputValue = 0;
      
      int returnInt() {
          std::cout << "Returning your int" << std::endl;
          return inputValue;
      }
      
      string returnString() {
          std::cout << "Returning your string" << std::endl;
          return "Your string";
      }
      
      int main() {
          std::cout << "Please type in a number" << "\t";
          std::cin >> inputValue;
          if (inputValue > 5) {
              returnInt();
          }
          else {
              returnString();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-11-19
        • 1970-01-01
        • 1970-01-01
        • 2021-12-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多