I've been diving into C++ lately, and I've been giving STL a go. I'm encountering a problem that I cannot seem to solve. I'm guessing it involves me not understanding how C++ deduces types, but I'm not sure. Here is the code that works
template <typename T>
auto most_frequent_element(const std::vector<std::reference_wrapper<T>> &vector) -> boost::optional<std::pair<const std::reference_wrapper<T>, size_t>> {
if (vector.empty()) {
return{};
}
std::map<std::reference_wrapper<T>, size_t> individual_counts = {};
std::for_each(vector.begin(), vector.end(), [&individual_counts](auto &element) {
auto result = individual_counts.emplace(element, 0);
(*result.first).second++;
});
return *std::max_element(individual_counts.begin(), individual_counts.end(), [](auto &a, auto &b) {
return a.second < b.second;
});
}
And this is how I might call it
auto main(int argc, char *argv[]) -> int {
std::vector<char> test = { 'a', 'a', 'b', 'b', 'c'};
auto result = most_frequent_element(std::vector<std::reference_wrapper<char>>(test.begin(), test.end()));
if (result) {
std::cout << (*result).first << " " << (*result).second << std::endl;
}
else {
std::cout << "Empty input list." << std::endl;
}
return EXIT_SUCCESS;
}
So that works. But if I create a simple method to eliminate the need to copy the vector manualy, like so
template <typename T>
auto most_frequent_element_2(const std::vector<T> &vector) -> boost::optional<std::pair<const std::reference_wrapper<T>, size_t>> {
most_frequent_element(std::vector<std::reference_wrapper<T>>(vector.begin(), vector.end()));
}
and call it like this
auto main(int argc, char *argv[]) -> int {
std::vector<char> test = { 'a', 'a', 'b', 'b', 'c'};
auto result = most_frequent_element_2(test);
if (result) {
std::cout << (*result).first << " " << (*result).second << std::endl;
}
else {
std::cout << "Empty input list." << std::endl;
}
return EXIT_SUCCESS;
}
I get the following error
Error C2664 'std::reference_wrapper<char>::reference_wrapper(std::reference_wrapper<char> &&)': cannot convert argument 1 from 'const char' to 'char &'
I'm confused because how I see it they should do the same thing. If I am wrong can someone point me in the right direction.
P.S. I'm working in Visual Studio 2015
Update: Added const constraint to return type of functions to correctly reflect the fact that the *max_element returns a const key. (suggested by @dyp)