3

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

因此,我四处寻找可能找到了一些示例代码,但不幸的是我找不到与该主题匹配的任何内容。

我想要一个像...这样的功能

int myCoolFunction(int myParam1) {
    return 93923;
}

处理不同的类型以返回多种不同类型的值,例如

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

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

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

注意:因此每次返回元素的顺序和计数都将相同 - > 集合保持相同(就像1.:double, 2.:int在每种情况下一样)

4

5 回答 5

4

如果要返回多个值,可以返回包装不同值的类的实例。

如果您不关心丢失语义,则可以返回1std::tuple

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

如果你想强制类型(例如,有 astd::string而不是 a 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 的编译器,你可以利用模板参数推导并简单地返回std::tuple{5, "nice weather", 5.5, myCoolMat}

于 2018-04-10T15:11:09.110 回答
3

是的,从 C++11 开始,一个函数可以 std::tuple在标准库中返回多种类型的不同值:

#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);
}

并且这里证明了这两个版本都可以编译(没有cv::Mat- 我认为 GodBolt 没有可用的)。

笔记:

  • 如果您使用std::make_tuple,则类型可能与您期望的不完全一致。例如,在这种情况下,您将得到一个char *虽然在明确定义元组时您可以强制它std::string像我上面那样。这通常不是问题。
  • 如果某些数据很大,您可以尝试使用std::move它,以避免复制整个数据,例如传递std::move(myCoolMat).
于 2018-04-10T15:11:08.320 回答
2

您可以返回一个结构或使用 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};
}
于 2018-04-10T15:10:57.663 回答
0

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

一种方法是使用

std::shared_ptr<void>

作为返回类型。这是允许的,因为std::shared_ptr支持类型擦除。(不幸的是,std::unique_ptr并非如此,您必须排除这种可能性。)

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

参考:为什么 shared_ptr<void> 合法,而 unique_ptr<void> 格式不正确?

于 2018-04-10T15:12:12.173 回答
-4

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

于 2018-04-10T15:06:54.110 回答