如何从一个函数中 return 多个类型?
How to return more than one type from a function?
背景故事。
在 Excel 中的 VBA 中,我创建了一个函数来计算两条线(向量)之间的最短距离。此函数 returns 表观交点,以及它们之间的实际距离。
为了完成这项工作,我最终传递了一个数组,然后整理出了之后的内容。它有效,但阅读和使用起来很笨重。
在 C++ 中,我制作了一个类似的函数,return是问题所在。
struct point3D
{
double x,y,z;
}
point3D findIntersect(const vec3& vector1, const vec3& vector2)
{
// Do stuff...
return point;
}
问题:
我也想 return 长度,因为它使用了部分原始计算。不过大多数时候我只想要重点
我看过的可能的解决方案是:
为距离写一个单独的函数。当我想要他们两个时,需要做很多额外的工作。
- 为这个函数创建一个自定义结构。 似乎有点矫枉过正。
- Return 一个类似于 VBA 函数的数组。 生成的代码不是很直观,使用时需要小心。
- 使用可选参数作为对变量的引用来存储距离。 无效。编译器不允许我更改可选参数。
- 使用这样的参数列表
function(const argin1, const argin2, argout&, argout2&)
。 呃!将要求用户始终期望输出每个变量。
我看过成对的例子,但它们看起来必须是相同的数据类型。我基本上想要 return 一个 point3D
和一个 double
.
有没有人有更优雅的解决方案来return从一个函数中获取多个值?
您可以使用 std::pair<point3D, double>
。还有一个std::tuple
,当你需要return两个以上的值时。 (请注意,正如您提到的那样,对值或元组值没有相同类型的东西。)
你肯定可以使用 pairs.
std::pair<point3D, double> findIntersect(const vec3& vector1, const vec3& vector2);
因为您不想定义自定义结构或 class,我假设您希望 return 值只是一个点。所以,我建议你使用一个可选的指针参数,它的默认值为 NULL,如果它不是 NULL,你将距离存储在它指向的变量中。
point3D findIntersect(const vec3 &v1, const vec3 &v2, double *dist = NULL) {
// ...
if (dist) {
// find the distance and store in *dist
}
return ... ;
}
C++ 允许您重载函数,即使用相同的名称,但参数类型不同。您可以 return point3D
作为 return 值,并通过提供单独的重载使 length
引用参数出现 "optional":
point3D findIntersect(const vec3& vector1, const vec3& vector2) {
double ignore;
return findIntersect(vector1, vector2, ignore);
}
point3D findIntersect(const vec3& vector1, const vec3& vector2, double &length) {
... // Implementation goes here
}
不想取回长度的调用者会调用两个参数的重载,而想要长度的调用者会调用三个参数的重载。在这两种情况下,实现都是相同的,双参数调用提供对长度的忽略变量的引用。
我仍然认为你可以而且应该为你的代码创建结构(如果你的代码不是实时的..)结构很常见,并且在你需要扩展你的代码的情况下给你robastics和灵活性.依赖于你代码中的这些键值对,然后在几个月后意识到你需要在 10 个地方更改它......:)
Straustrup 和 Sutter 建议为此使用 tuple/tie
:F.41: Prefer to return tuples to multiple out-parameters
Point3D point3D;
double distance;
std::tie(point3D, distance) = findIntersect(/*..params..*/);
其中:
std::tuple<Point3D, double> findIntersect(/*..params..*/)
{
Point3D point3D;
double distance;
// calculate point3D & distance
return std::make_tuple(point3D, distance);
}
背景故事。 在 Excel 中的 VBA 中,我创建了一个函数来计算两条线(向量)之间的最短距离。此函数 returns 表观交点,以及它们之间的实际距离。 为了完成这项工作,我最终传递了一个数组,然后整理出了之后的内容。它有效,但阅读和使用起来很笨重。
在 C++ 中,我制作了一个类似的函数,return是问题所在。
struct point3D
{
double x,y,z;
}
point3D findIntersect(const vec3& vector1, const vec3& vector2)
{
// Do stuff...
return point;
}
问题: 我也想 return 长度,因为它使用了部分原始计算。不过大多数时候我只想要重点
我看过的可能的解决方案是:
为距离写一个单独的函数。当我想要他们两个时,需要做很多额外的工作。
- 为这个函数创建一个自定义结构。 似乎有点矫枉过正。
- Return 一个类似于 VBA 函数的数组。 生成的代码不是很直观,使用时需要小心。
- 使用可选参数作为对变量的引用来存储距离。 无效。编译器不允许我更改可选参数。
- 使用这样的参数列表
function(const argin1, const argin2, argout&, argout2&)
。 呃!将要求用户始终期望输出每个变量。
我看过成对的例子,但它们看起来必须是相同的数据类型。我基本上想要 return 一个 point3D
和一个 double
.
有没有人有更优雅的解决方案来return从一个函数中获取多个值?
您可以使用 std::pair<point3D, double>
。还有一个std::tuple
,当你需要return两个以上的值时。 (请注意,正如您提到的那样,对值或元组值没有相同类型的东西。)
你肯定可以使用 pairs.
std::pair<point3D, double> findIntersect(const vec3& vector1, const vec3& vector2);
因为您不想定义自定义结构或 class,我假设您希望 return 值只是一个点。所以,我建议你使用一个可选的指针参数,它的默认值为 NULL,如果它不是 NULL,你将距离存储在它指向的变量中。
point3D findIntersect(const vec3 &v1, const vec3 &v2, double *dist = NULL) {
// ...
if (dist) {
// find the distance and store in *dist
}
return ... ;
}
C++ 允许您重载函数,即使用相同的名称,但参数类型不同。您可以 return point3D
作为 return 值,并通过提供单独的重载使 length
引用参数出现 "optional":
point3D findIntersect(const vec3& vector1, const vec3& vector2) {
double ignore;
return findIntersect(vector1, vector2, ignore);
}
point3D findIntersect(const vec3& vector1, const vec3& vector2, double &length) {
... // Implementation goes here
}
不想取回长度的调用者会调用两个参数的重载,而想要长度的调用者会调用三个参数的重载。在这两种情况下,实现都是相同的,双参数调用提供对长度的忽略变量的引用。
我仍然认为你可以而且应该为你的代码创建结构(如果你的代码不是实时的..)结构很常见,并且在你需要扩展你的代码的情况下给你robastics和灵活性.依赖于你代码中的这些键值对,然后在几个月后意识到你需要在 10 个地方更改它......:)
Straustrup 和 Sutter 建议为此使用 tuple/tie
:F.41: Prefer to return tuples to multiple out-parameters
Point3D point3D;
double distance;
std::tie(point3D, distance) = findIntersect(/*..params..*/);
其中:
std::tuple<Point3D, double> findIntersect(/*..params..*/)
{
Point3D point3D;
double distance;
// calculate point3D & distance
return std::make_tuple(point3D, distance);
}