putting together iterator, std_max and lambda expression

Sep 18, 2019 at 4:43pm
Hello
I'm trying to find the biggest area size (width * height) of a list of objects inside a vector, and then modify the found object.
Uo to now I have this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <algorithm>
#include <vector>

class Block{
public:
	int x, y;
};

int main(){
	std::vector<Block> blocks;
	Block block;
	block.x = 10;
	block.y = 12;
	blocks.push_back(block);
	std::vector<Block>::iterator it = std::max(blocks.begin(), blocks.end(), [] (Block a, Block b){return a.x*a.y < b.x*b.y;});
	blocks[it].x = 0;
}


But ai get this error, which I dont understand at all, but I suspectbis from the lambda expression:

In function 'int main()':
16:8: error: no match for 'operator[]' (operand types are 'std::vector<Block>' and 'std::vector<Block>::iterator {aka __gnu_cxx::__normal_iterator<Block*, std::vector<Block> >}')
16:8: note: candidates are:
In file included from /usr/include/c++/4.9/vector:64:0,
from /usr/include/c++/4.9/bits/random.h:34,
from /usr/include/c++/4.9/random:49,
from /usr/include/c++/4.9/bits/stl_algo.h:66,
from /usr/include/c++/4.9/algorithm:62,
from 1:
/usr/include/c++/4.9/bits/stl_vector.h:779:7: note: std::vector<_Tp, _Alloc>::reference std::vector<_Tp, _Alloc>::operator[](std::vector<_Tp, _Alloc>::size_type) [with _Tp = Block; _Alloc = std::allocator<Block>; std::vector<_Tp, _Alloc>::reference = Block&; std::vector<_Tp, _Alloc>::size_type = long unsigned int]
operator[](size_type __n) _GLIBCXX_NOEXCEPT
^
/usr/include/c++/4.9/bits/stl_vector.h:779:7: note: no known conversion for argument 1 from 'std::vector<Block>::iterator {aka __gnu_cxx::__normal_iterator<Block*, std::vector<Block> >}' to 'std::vector<Block>::size_type {aka long unsigned int}'
/usr/include/c++/4.9/bits/stl_vector.h:794:7: note: std::vector<_Tp, _Alloc>::const_reference std::vector<_Tp, _Alloc>::operator[](std::vector<_Tp, _Alloc>::size_type) const [with _Tp = Block; _Alloc = std::allocator<Block>; std::vector<_Tp, _Alloc>::const_reference = const Block&; std::vector<_Tp, _Alloc>::size_type = long unsigned int]
operator[](size_type __n) const _GLIBCXX_NOEXCEPT
^
/usr/include/c++/4.9/bits/stl_vector.h:794:7: note: no known conversion for argument 1 from 'std::vector<Block>::iterator {aka __gnu_cxx::__normal_iterator<Block*, std::vector<Block> >}' to 'std::vector<Block>::size_type {aka long unsigned int}'
In file included from /usr/include/c++/4.9/algorithm:61:0,
from 1:
/usr/include/c++/4.9/bits/stl_algobase.h: In instantiation of 'const _Tp& std::max(const _Tp&, const _Tp&, _Compare) [with _Tp = __gnu_cxx::__normal_iterator<Block*, std::vector<Block> >; _Compare = main()::<lambda(Block, Block)>]':
15:123: required from here
/usr/include/c++/4.9/bits/stl_algobase.h:264:26: error: no match for call to '(main()::<lambda(Block, Block)>) (const __gnu_cxx::__normal_iterator<Block*, std::vector<Block> >&, const __gnu_cxx::__normal_iterator<Block*, std::vector<Block> >&)'
if (__comp(__a, __b))
^
15:76: note: candidates are:
In file included from /usr/include/c++/4.9/algorithm:61:0,
from 1:
/usr/include/c++/4.9/bits/stl_algobase.h:264:26: note: bool (*)(Block, Block) <conversion>
if (__comp(__a, __b))
^
/usr/include/c++/4.9/bits/stl_algobase.h:264:26: note: candidate expects 3 arguments, 3 provided
15:95: note: main()::<lambda(Block, Block)>
15:95: note: no known conversion for argument 1 from 'const __gnu_cxx::__normal_iterator<Block*, std::vector<Block> >' to 'Block'



Any idea on how to make it work?
Thanks in advance
Sep 18, 2019 at 5:05pm
 
it->x = 0;


I miss that bug with std::max_element. Shame on me.
Last edited on Sep 18, 2019 at 5:30pm
Sep 18, 2019 at 5:22pm
Furthermore, the std::max compares two values (or values in initializer_list) and returns a value. You give two iterators and expect iterator.

That would be ok, if they were the values you want to compare. They are not.

You seem to want the largest from range. For that there is std::max_element.


As Thomas hints, an iterator is not an index. It is closer to a pointer; something to dereference in order to access the actual value.
Sep 19, 2019 at 1:49pm
oh, I see. I tought std::max could return a reference to an element, and not just a copy.
I'm using max_element then. thanks for the help!
Topic archived. No new replies allowed.