std::string and std::wostream

  • Thread starter Pierre Barbier de Reuille
  • Start date
P

Pierre Barbier de Reuille

Hi,

I was wondering why there was no predefine operator<< puting a
std::string into a std::wostream. The strangest is that something
similar to this would work:

std::wostream& operator<<(std::wostream& stream, std::string str)
{
stream << str.c_str();
return stream;
}

The only problem with this solution is it invalidate the different
iterators you have on the string (because of the call to c_str), while
the operator<< should not do that.

Thanks,

Pierre
 
K

Kai-Uwe Bux

Pierre said:
Hi,

I was wondering why there was no predefine operator<< puting a
std::string into a std::wostream. The strangest is that something
similar to this would work:

std::wostream& operator<<(std::wostream& stream, std::string str)
{
stream << str.c_str();
return stream;
}

The only problem with this solution is it invalidate the different
iterators you have on the string (because of the call to c_str), while
the operator<< should not do that.

No, it would not invalidate iterators: you are passing str by value.
Therefore, a copy is being made and the call to c_str() invalidates
iterators to that copy but not to the original. However, you probably
didn't mean to pass by value.

On the other hand, I think that the above implementation does not deal
properly with embedded 0 characters. To be safe, I would start from:

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>

std::wostream & operator<< ( std::wostream & ostr,
std::string const & str ) {
std::copy ( str.begin(), str.end(),
std::eek:stream_iterator<char, std::wchar_t>( ostr ) );
return ( ostr );
}


Best

Kai-Uwe Bux
 
D

Daniel T.

Pierre Barbier de Reuille said:
Hi,

I was wondering why there was no predefine operator<< puting a
std::string into a std::wostream. The strangest is that something
similar to this would work:

std::wostream& operator<<(std::wostream& stream, std::string str)
{
stream << str.c_str();
return stream;
}

The only problem with this solution is it invalidate the different
iterators you have on the string (because of the call to c_str), while
the operator<< should not do that.

Calling c_str() on a string doesn't invalidate any iterators that may
point into the string.
 
P

Pierre Barbier de Reuille

Daniel said:
Calling c_str() on a string doesn't invalidate any iterators that may
point into the string.

Sadly enough it may ! See section 23.5.2 §5 in the norm for reference:

"""
References, pointers, and iterators referring to the elements of a
basic_string sequence may be invalidated by the following uses of that
basic_string object:
— As an argument to non-member functions swap() (21.3.7.8), operator>>()
(21.3.7.9), and getline() (21.3.7.9).
— As an argument to basic_string::swap().
— Calling data() and c_str() member functions.
— Calling non-const member functions, except operator[](), at(),
begin(), rbegin(), end(), and rend().
— Subsequent to any of the above uses except the forms of insert() and
erase() which return iterators, the first call to non-const member
functions operator[](), at(), begin(), rbegin(), end(), or rend().
"""

Pierre
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top