Reputation: 797
I am trying to write a generic function to compute barycenter of a bunch of numbers, I found the following one but I am unable to use it:
template <typename Container>
auto getBarycenter(Container &&cont)
{
decltype(cont[0]) res(0.0f);
for (auto &v : cont)
res += v;
return res / static_cast<float>(cont.size());
}
I am new to templates, the data structure I am trying to operate on is std::vector < cv::Point3f >
(from the OpenCV namespace).
EDIT:
Here is the calls I tried:
std::vector<float> vector;
auto value = vector.getBarycenter<std::vector>();
auto value = vector.getBarycenter<std::vector <cv::Point3f> >();
Upvotes: 0
Views: 66
Reputation: 4655
Given the information you provided, there's at least one problem in that snippet showed.
decltype(cont[0])
evaluates to (potentially non-const) lvalue reference to the containers values. This can be fixed using std::decay_t
(or std::remove_cvref
, if you have access to c++20) which will remove the "reference-ness" and constness from the type.
template <typename Container>
auto getBarycenter(Container &&cont)
{
std::decay_t<decltype(cont[0])> res(0.0f);
for (auto &v : cont)
res += v;
return res / static_cast<float>(cont.size());
}
Alternatively, as mentioned by @Remy Lebeau you can use value_type
if you're using std containers:
typename std::decay_t<Container>::value_type res(0.0f);
Also you should probably better default initialize res
rather than use a float literal.
Live example here.
Upvotes: 3