Shoe
Shoe

Reputation: 76240

Is `std::string::iterator` guaranteed not to be a pointer to char?

Given that an overload of operator<< on std::ostream for pointer to char exists, and given that the standard specifies the synopsis of the std::string class to be the following, in §21.4:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
  public:
    [...]
    typedef implementation-defined iterator;
    typedef implementation-defined const_iterator; 
    [...]
  };
}

and finally given that the requirements for iterator and const_iterator for a Container concept are, in §23.2/4:

enter image description here

and a pointer to char would satisfy them; am I reading it correctly that it's implementation defined whether the following code compiles or not?

std::string string = "abc";
std::cout << begin(string);

On a side note, both GCC and Clang seem not to accept it.

Upvotes: 5

Views: 762

Answers (2)

skyking
skyking

Reputation: 14360

Short answer: No.

Long answer:

That could depend on what you put in the wording "pointer to char". Either it could be strictly interpreted as the formal type char* or similar or more loosely as anything that's an address to memory where a character resides.

I don't see that the overload you're mentioning actually exists in the standard, but nevertheless it's possible that other required overloads exists. The one you takes as example doesn't seem to exist (and it doesn't seem to be any other places with overloads with std::string::iterator vs char*), you cant for example output a std::string::iterator for example:

std::string s = "abc";
std::string.iterator p = s.begin();

std::cout << p; // fails

Since the standard says that the methods and functions should exist and even if we take the requirement that the implementation need not actually formally define them the way that's indicated in the standard, but only to behave as if it were (compare the requirement of the translation sequence) you still probably would need to have the distinction of the overloads since you're supposed to be able to take a pointer to them (and you need to be able to know what type that pointer should have).

For example if we have a specification saying that it should behave as if void foo(long) and void foo(int) were defined and the implementation actually only contain void foo(long) it would work fine as long as the programs only issues functions calls to foo as shorts would silently be converted to int, but as soon as some program contains code to take a pointer to the function it would fail since the type it would store the pointer in simply wouldn't match:

 void foo(long);

 foo(1L); // works fine
 foo(1);  // works probably fine, 1 is converted to long first

 void (*f)(int) = foo;  // this fails as it cant convert void(*)(long) to void(*)int

From this we can conclude that std::string::iterator would probably need to be of a different formal type (still if there exists a overload on char* vs std::string::iterator). Note though that even if char* appears, that char const* is a distinct type.

However if you're just by "pointer to char" only means an address in memory of a character (not necessarily of the type char*) it certainly can be. One could even argue that it may be quite likely that it is.

Upvotes: 2

Peter
Peter

Reputation: 36597

The (actual) types of the std::string's iterators are implementation defined. There is no requirement that they be a pointer, and also no requirement that they not be a pointer.

There is also no requirement that the standard streams have a variant of operator<<() that accepts an iterator from any standard container (including std::string). Conversely, there no requirement that it shall not. Which means it is implementation-defined whether the code at the end of your post compiles.

Upvotes: 0

Related Questions