函数可以返回不同类型的多个值吗?

时间:2018-04-10 15:03:55

标签: c++ function return-type multiple-return-values

它认为从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

5 个答案:

答案 0 :(得分:4)

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

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

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并只返回std::tuple{5, "nice weather", 5.5, myCoolMat}

答案 1 :(得分:2)

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

使用struct,你可以这样做:

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

答案 2 :(得分:2)

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

here is proof both of these versions compile(没有cv::Mat - 我认为GodBolt不具备此功能。)

注意:

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

答案 3 :(得分:0)

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

一种方式,实际上是相当邪恶的,因为你通过取消内容来加重呼叫网站是使用

std::shared_ptr<void>

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

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

参考:Why is shared_ptr<void> legal, while unique_ptr<void> is ill-formed?

答案 4 :(得分:-4)

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