Std:: stringstream и метод str
Я заметил что-то при попытке использовать объект stringstream. Вот бесполезный пример, чтобы объяснить это:
stringstream ss ;
ss << "my string" ;
cout << ss.str() << endl ;
Не эквивалентен
cout << (stringstream() << "my string").str() << endl ;
Это приводит к ошибке компиляции, в которой говорится, что "class std:: basic_ostream не имеет имени с именем str.
Я не могу это легко объяснить. Это не критично для моего приложения, но я уверен, что это скрывает трюк С++, который нужно понять.
Примечание: я использую gcc с С++ 14
Ответы
Ответ 1
operator<<
не определен для std::stringstream
, но для его базового класса std::ostream
, поэтому он не возвращает ссылку на std::stringstream
и, следовательно, метод str()
( который является методом std::stringstream
), не найден.
Технически, это на самом деле std::basic_stringstream<CharT,Traits>
и std::basic_ostream<CharT,Traits>
, но вы получаете идею:)
Ответ 2
Проблема с этим:
cout << (stringstream() << "my string").str() << endl;
Это выражение stringstream() << "my string"
возвращает объект std::ostream&
, а не std::stringstream
.
Вы можете исправить это, указав некоторые соответствующие перегрузки:
template<typename Type>
std::stringstream& operator<<(std::stringstream& ss, const Type& type)
{
static_cast<std::ostream&>(ss) << type;
return ss;
}
template<typename Type>
std::stringstream& operator<<(std::stringstream&& ss, const Type& type)
{
static_cast<std::ostream&>(ss) << type;
return ss;
}
template<typename Type>
std::stringstream& operator>>(std::stringstream& ss, Type& type)
{
static_cast<std::istream&>(ss) >> type;
return ss;
}
template<typename Type>
std::stringstream& operator>>(std::stringstream&& ss, Type& type)
{
static_cast<std::istream&>(ss) >> type;
return ss;
}
Теперь, когда вы используете операторы <<
и >>
для объекта std::stringstream
, он будет вызывать эти перегрузки, и они возвратят std::stringstream&
, чтобы вы могли напрямую использовать его интерфейс.