一个函数可以 return 多个不同类型的值吗?

Can a function return multiple values of varying types?

它认为从 C++ 函数调用中 return 多个值(具有不同类型!)会很有趣。

所以我环顾四周,也许找到了一些示例代码,但遗憾的是我找不到与该主题匹配的任何内容。

我想要一个功能,例如...

int myCoolFunction(int myParam1) {
    return 93923;
}

处理不同类型 return 多种不同类型的值,例如

?whatever? myCoolFunction(int myParam1) {
    return { 5, "nice weather", 5.5, myCoolMat }
}

使用 C++ 可以实现这样的事情吗 (我的想法是使用一个特殊的 AnyType 向量,但因此我找不到示例代码) 或者我必须继续使用这些类型的调用吗? (见下文)

void myCoolFunction(cv::Mat &myMat, string &str){
   // change myMat
   // change str
}

注意:因此每次 returned 元素的顺序和计数都是相同的 - > 集合保持相同(如 1.:double, 2.:int 在每种情况下)

返回 std::variant 的 std::vector,其中 std::variant 是根据您选择的类型参数化的模板。如果任何类型实际上是可能的,我不确定你为什么要用结构来做,而不是简单地写入内存 space;对结构中的对象和类型没有确定性概念的价值很低。

您可以 return 结构或使用 std::tuple。

使用结构,你可以做:

myStruct create_a_struct() {
  return {20, std::string("baz"), 1.2f};
}

和 std::tuple

std::tuple<int, std::string, float> create_a_tuple() {
  return {20, std::string("baz"), 1.2f};
}

是的,一个函数可以 return 多种类型的不同值,在一个 std::tuple 中,自 C++11 起在标准库中可用:

#include <tuple>

std::tuple<int, std::string, double, cv::Mat>
myCoolFunction(int myParam1) {
    return { 5, "nice weather", 5.5, myCoolMat }
}

如果你被允许使用 C++14 代码,你甚至不必声明类型:

#include <tuple>

auto myCoolFunction(int myParam1) {
     return std::make_tuple(5, "nice weather", 5.5, myCoolMat);
}

here is proof both of these versions compile(没有 cv::Mat - 我认为 Godbolt 没有可用的)。

备注:

  • 如果您使用 std::make_tuple,类型可能与您期望的不完全一样。例如,在这种情况下,您将得到一个 char *,尽管在显式定义元组时您可以像上面那样强制它成为 std::string。这通常不是问题。
  • 如果某些数据很大,您可以尝试 std::move 它,以避免复制整个数据,例如通过 std::move(myCoolMat).

如果您想 return 多个值,您可以 return 一个 class 包装不同值的实例。

如果你不关心失去语义,你可以return一个std::tuple1:

auto myCoolFunction(int myParam1) {
    return std::make_tuple(5, "nice weather", 5.5, myCoolMat);        
}

如果你想强制类型(例如,使用 std::string 而不是 const char *):

std::tuple<int, std::string, double, cv::Mat> myCoolFunction(int myParam1) {
    return {5, "nice weather", 5.5, myCoolMat};
}

在这两种情况下,您都可以使用 std::get:

访问这些值
auto tup = myCoolFunction(3);
std::get<0>(tup); // return the first value
std::get<1>(tup); // return "nice weather"

1 如果你有一个 C++17 兼容的编译器,你可以使用 template argument deduction 并简单地 return std::tuple{5, "nice weather", 5.5, myCoolMat}.

(真正的娱乐和展示 C++ 的力量而不是其他任何东西的答案。)

一种方法,实际上是相当邪恶的,因为你在取消选择内容时给调用站点带来了负担,那就是使用

std::shared_ptr<void>

作为 return 类型。这是允许的,因为 std::shared_ptr 支持 类型擦除 。 (不幸的是,std::unique_ptr 没有,所以你必须排除这种可能性。)

很明显,在函数中,您需要使用 std::make_shared 或类似的。

参考: