0

Does C++ standard guarantee that the following code is correct?

#include <iostream>
#include <vector>

std::vector<int>::iterator i = {};

int main()
{
    if (i == std::vector<int>::iterator{})
    {
        std::cout << "it is empty" << std::endl;
    }

    return 0;
}

(at least it works with MSVC2017 with both std::vector<int> and std::set<int>)

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Dmitriano
  • 1,878
  • 13
  • 29
  • 3
    Does [this thread](https://stackoverflow.com/questions/3395180/what-is-an-iterators-default-value) provide the answer you are looking for? – lubgr Sep 28 '20 at 09:47
  • @lubgr in that thread the iterators are not initialized, but I explicitly initialize the iterator with `{}` – Dmitriano Sep 28 '20 at 09:50
  • 2
    @Dmitriano Classes with constructors cannot be uninitialised; not specifying parentheses or braces nonetheless means the default constructor gets called. – underscore_d Sep 28 '20 at 09:51
  • 2
    That's only a syntactical difference. In both the linked thread and your example, the iterators are default constructed. – lubgr Sep 28 '20 at 09:52
  • @lubgr yes, sure. So it has a "singular value" like an uninitialized pointer. – Dmitriano Sep 28 '20 at 09:54
  • 2
    @Dmitriano Uninitialized pointers can't be compared. If `std::vector::iterator` was `int*`, then yes this would work since it would explicitly become `nullptr`. Otherwise there's nothing stopping the iterator's `operator==` always being false if one of the iterators were default constructed. Also, the default constructor could be `explicit` making this just fail to compile or have the default constructor leave a member uninitialized instead of a `nullptr` making the comparison undefined behaviour. – Artyer Sep 28 '20 at 10:37
  • 1
    @underscore_d Iterators don't have to be class types. For example `int x[10]; std::begin(x);` produces an `int *` which is an iterator on `x`. I believe `std::vector` and `std::array` iterators could also be pointers. It is inaccurate to say that iterators cannot be uninitialized. – François Andrieux Sep 28 '20 at 11:57
  • @underscore_d Is not it a good idea to have `std::null(x)` along with `std::begin(x)` and `std::end(x)`? – Dmitriano Sep 28 '20 at 12:36
  • 1
    No, `std::null(x)` would not be a good idea. Iterators designate sequences. An iterator that is not associated with a sequence have a "singular value". "Results of most expressions are undefined for singular values; the only exceptions are destroying an iterator that holds a singular value, the assignment of a non-singular value to an iterator that holds a singular value, and, for iterators that meet the Cpp17DefaultConstructible requirements, using a value-initialized iterator as the source of a copy or move operation." [iterator.requirements.general]/7. – Pete Becker Sep 28 '20 at 13:23

0 Answers0