iterators, last vs end


When I run the code below, I get this error:
Expression: cannot dereference end map/set iterator

I'm confused about the meaning of last versus end, or do they sometimes mean the same thing?

The method find() returns last if the value isn't found. I know that end is the position one past the last element. What does last mean? Don't some methods actually return the last element when the value isn't found? It seems like I remember that somewhere.

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <set>
using namespace std;

int main()
{
	int numbers[] = {3, 2, 1};
	set<int> my_set(numbers, numbers + 3);
	cout << *(find(my_set.begin(), my_set.end(), 5)); 

	return 0;
}
> Don't some methods actually return the last element when the value isn't found?

No. And we could use the find function of the set (faster, with logarithmic complexity).

std::set<>::find()
"Return value: Iterator to an element with key equivalent to key. If no such element is found, past-the-end (see end()) iterator is returned."
https://en.cppreference.com/w/cpp/container/set/find
last is the last element in the container (often called by .back() function). end is one-past last element (often obtained by .end() function). These aren't the same.

You don't de-reference .end() (or equivalent). If an iterator is returned then you need check it's not .end() before it's dereferenced.

1
2
3
4
5
6
7
8
9
10
11
12
13
include <iostream>
#include <set>
#include <algorithm>

int main() {
	const int numbers[] {3, 2, 1};
	const std::set<int> my_set(numbers, numbers + 3);

	if (const auto itr {std::find(my_set.begin(), my_set.end(), 5)}; itr != my_set.end())
		std::cout << *itr << '\n';
	else
		std::cout << "Not found\n";
}


Or using std::set::find():

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
#include <set>

int main() {
	const int numbers[] {3, 2, 1};
	const std::set<int> my_set(numbers, numbers + 3);

	if (const auto itr {my_set.find(5)}; itr != my_set.end())
		std::cout << *itr << '\n';
	else
		std::cout << "Not found\n";
}


Last edited on
std::end returns an iterator to the element PAST the last element in the container.
https://en.cppreference.com/w/cpp/iterator/end
Lets see:
https://en.cppreference.com/w/cpp/algorithm/find
1
2
template< class InputIt, class T >
constexpr InputIt find( InputIt first, InputIt last, const T& value );

Return value
Iterator to the first element satisfying the condition or last if no such element is found.

Yes, the reason for confusion is obvious.

Lets use different names for arguments:
1
2
template< class InputIt, class T >
constexpr InputIt find( InputIt XXX, InputIt YYY, const T& ZZZ );

Return value
Iterator to the first element satisfying the condition or YYY if no such element is found.

So, for the OP function call: find(my_set.begin(), my_set.end(), 5)
Returns iterator to the element that has value 5 or my_set.end() if no such element is found.

The "last" refers to function's argument, not to the last element of container.
Topic archived. No new replies allowed.