std::tuple¶
std::tuple
is a fixed size container that may contain heterogeneous values.
Ruby does not have the concept of a tuple, but it can be mapped to a fixed size array. Thus Rice unwraps std::tuple
instances into an array that has the same size as the tuple.
Rice also support passing a Ruby array to C++ api that takes tuples.
Out Parameters¶
Prior to the introduction of tuples, C++ did not have a good way of returning multiple values from a function. One workaround was to return values via function parameters that are pointers. These are known as out
parameters.
For example, the minMaxLoc function in OpenCV is defined as:
void cv::minMaxLoc(cv::InputArray src,
double * minVal,
double * maxVal = 0,
Point * minLoc = 0,
Point * maxLoc = 0,
cv::InputArray mask = cv::noArray() )
All of minVal
, maxVal
, minLoc
and maxLoc
are out parameters designed to return values.
One way to wrap this function is to use Buffers.
An alternative approach is to use std::tuple
.
define_module_function("min_max_loc", [](cv::InputArray src, cv::InputArray mask = cv::noArray()) -> std::tuple<double, double, cv::Point, cv::Point>
{
double minVal = 0;
double maxVal = 0;
cv::Point minLoc = 0;
cv::Point maxLoc = 0;
cv::minMaxLoc(src, &minVal, &maxVal, &minLoc, &maxLoc, mask);
return std::forward_as_tuple(minVal, maxVal, minLoc, maxLoc);
},
Arg("src"), Arg("mask") = static_cast<cv::InputArray>(cv::noArray()));
Then to call the method from Ruby:
mat = Cv::Mat.new(2, 2, CV_8UC4, cv::Scalar.new(10, 20, 30, 40))
min_val = 10
min_val, max_val, min_loc, max_loc = min_max_loc(mat.input_array, min_val)