"Peter Dimov"
No, a singular iterator is not a valid object and it fulfills no invariants. You can't even copy it without UB. The ofstream can be made to fulfill its invariant if we define its invariant as "true", I guess, or something with a similar utility.
A singular iterator is a valid object. It's use is limited, however: You can only assign a valid value to it. It may be useful to distinguish between an invalid and an uninitialized object.
A default-constructed std::string is fine. You are not breaking the invariant with invoking op[], you are supplying an invalid index to it. BTW, did you know that the const version of op[] is required to return 0 for s[0] :-) How exactly is it supposed to return 0 when the return type is a char const& is left as an exercise for the implementer.
That's not true, see Section 21.3.4 of the 2003 C++ Standard for the definition of operator[] for std::basic_string<> (note that std::string is a typedef for std::basic_string<char>): [quote] const_reference operator[](size_type pos) const; reference operator[](size_type pos); Returns: If pos < size(), returns data()[pos]. Otherwise, if pos == size(), the const version returns charT(). Otherwise, the behavior is undefined. [/quote] This behaviour does not seem to be difficult to implement. The default constructor only needs to allocate an array of size 1 and initialize its single element with charT(). The constant version of operator[] can then return a constant reference to that element. -- Matthias Hofmann Anvil-Soft, CEO http://www.anvil-soft.com - The Creators of Toilet Tycoon http://www.anvil-soft.de - Die Macher des Klomanagers