I would like to unpack the members of a cv::Vec4f into its components.
cv::Vec4f line{0,1,2,3};
// What I currently have to do:
float x1 = line[0];
float y1 = line[1];
float x2 = line[2];
float y2 = line[3];
// What I would like to be able to do:
auto [x1, y1, x2, y2] = line;
When I do that I currently get a compilation error with the following text:
error: type cv::Vec<float, 4> decomposes into 1 element, but 4 names were provided
I think the error is because the binding immediately grabs the single underlying array element of the Mat class, when I want to be grabbing the elements of that.
cv::Vec4f line{0, 1, 2, 3};
// What compiles, but is ugly
auto [x1, y1, x2, y2] = line.val;
// Or
const auto& [underlying_data] = line;
auto [x1, y1, x2, y2] = underlying_data;
This works, but is really ugly and eliminates one of the main cases I wanted to use a structured binding, which is iterating through a std::vector<cv::Vec4f> using a range based for loop for example:
std::vector<cv::Vec2i> vecs{{1, 2}, {3, 4}};
for (const auto& [x, y] : vecs) {
... Do stuff
}
Which obviously does not compile due to the previously mentioned issue.
I ended up following the requirements listed on cppreference for what defines a structured binding: https://en.cppreference.com/w/cpp/language/structured_binding
And tried to follow the listed Case-2 of a type being "tuple-like"
So I copied
std::array'sget<>functions and tried to apply them tocv::Vechowever it feels a bit wrong to encroach on the cv namespace and really wrong to encroach on the std namespace.The following code seems to work for my desired use case, but maybe there's some way to reduce some of this boilerplate and just say regardless of what form you are getting, use the
getapplied toVec::val.Edit: From Cppreference for
tuple_elementandtuple_sizeuser specialization for program-defined types is specifically allowed to make them tuple-like, so I am no longer concerned about specializingVec. If you have access to C++20 ranges and aren't comfortable encroaching on the namespaces I recommend the solution by Daniel Langr.