Reputation: 45
Using the code from cplusplus.com, I am trying to find the max int value in an vector<std::string>
.
the vector is in std::string format and there is no choice here.
bool myfn(int i, int j)
{
return i < j;
}
vector<std::string> dat;
dat.push_back(2.1);
dat.push_back(5.3);
for (int l = 0; l < dat.size(); ++l)
{
std::cout << *std::max_element(dat.begin(), dat.end(), myfn) << '\n';
}
expected output:
3
error:
.cpp:76:93: error: no matching function for call to 'max_element(std::vector<std::basic_string<char> >&, std::vector<std::basic_string<char> >::size_type, bool (&)(int, int))'
How do you find the max value in a vector<std::string>
?
Upvotes: 0
Views: 6070
Reputation:
Pointers can be iterators. This is what allows you to use arrays as a range in standard library functions. myints
is an expression that refers to the first element of the array, and myints + 7
refers to one past the end of the array. Equivalently you can do std::begin(myints)
and std::end(myints)
. Standard containers expose iterators in the form of these member functions myvector.begin()
and myvector.end()
. You pass these iterators, not the container and size, to std::max_element
.
By default, std::max_element
uses operator<
to compare the elements. You don't need a comparator functor in this instance.
Your std::vector
's value_type
is std::string
, but you're trying to pass an int
. Either change the value_type
to int, or use a string conversion function, i.e. C++11's std::to_string
.
Finally, your loop is completely unnecessary. std::max_element
operators over a range.
std::vector<int> dat;
dat.push_back(1);
dat.push_back(3);
std::cout << *std::max_element(dat.begin(), dat.end()) << '\n';
Upvotes: 0
Reputation: 302922
You're calling max_element
with the wrong arguments. It takes two iterators and a function:
template <class ForwardIterator, class Compare>
ForwardIterator max_element (ForwardIterator first, ForwardIterator last,
Compare comp);
You're calling it with a vector and a size. The confusion might stem from the example on the reference you link where they do:
std::min_element(myints, myints +7, myfn)
// ^^^^^^ ^^^^^^^^^
// int* int*
In this case, both myints
and myints + 7
are of type int*
, and a raw pointer is an iterator. In your case however, you are passing two different types (vector<string>
and size_t
), neither of which is an iterator. So you need to instead do:
*std::max_element(dat.begin(), dat.end(), myfn)
Or, to illustrate something equivalent to the example in the reference (although definitely prefer the above):
std::string* first = &dat[0];
*std::max_element(first, first + dat.size(), myfn)
Which works because in this case I am passing two string*
's, which are iterators.
(Also based on your usage, dat
should be vector<int>
not vector<string>
.)
Upvotes: 4
Reputation: 101
Your std::vector dat declaration is wrong as you want to push_back int. std::max_element and std::min_element returns an iterator not value. You can have a look into the following example
#include <vector>
#include <algorithm>
#include <iostream>
int main()
{
std::vector<int> v {1,2,3,4,6};
auto biggest = std::max_element(std::begin(v), std::end(v));
std::cout << "Max element is " << *biggest
<< " at position " << std::distance(std::begin(v), biggest) << std::endl;
auto smallest = std::min_element(std::begin(v), std::end(v));
std::cout << "min element is " << *smallest
<< " at position " << std::distance(std::begin(v), smallest) << std::endl;
return 0;
}
Upvotes: 1
Reputation: 15934
You have a vector that is full of strings vector<std::string> dat;
but yet your comparison functions takes 2 integers. You might want to either change the type that is stored in the vector or change the comparison function you use. If you use integers then the default comparison operator will do what you want already without you needing to write a custom function.
Also std::max_element
expects to get iterators one for the start and one for the end, so you need to change your call to be something like std::max_element(dat.begin(), dat.end(), myfn)
. You might notice that the loop you have is actually not needed because you already go over that range with the call to std::max_element
all this loop does is compute the exact same value multiple times, you only need to compute it once.
Upvotes: 2