Рассмотрим следующую функцию:
void f(const char* str);
Предположим, что я хочу сгенерировать строку с использованием stringstream и передать ее этой функции. Если я хочу сделать это в одном из утверждений, я могу попробовать:
f((std::ostringstream() << "Value: " << 5).str().c_str()); // error
Это дает ошибку: 'str()' не является членом 'basic_ostream'. ОК, поэтому оператор < возвращает ostream вместо ostringstream - как насчет того, чтобы вернуть его обратно в ostringstream?
1) Является ли это безопасным?
f(static_cast<std::ostringstream&>(std::ostringstream() << "Value: " << 5).str().c_str()); // incorrect output
Теперь с этим вызывается вызов оператора < ('Value: "), который фактически вызывает оператор ostream < (void *) и печатает гексаговый адрес. Это неправильно, я хочу текст.
2) Почему оператор < на временном std:: ostringstream() вызов оператора ostream? Разумеется, у временного есть тип "ostringstream", а не "ostream"?
Я также могу временно использовать принудительный вызов оператора!
f(static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << "Value: " << 5).str().c_str());
Это, похоже, работает и передает значение "Значение: 5" в f().
3) Я полагаюсь теперь на поведение undefined? Отливки выглядят необычно.
Я знаю, что лучшая альтернатива - это что-то вроде этого:
std::ostringstream ss;
ss << "Value: " << 5;
f(ss.str().c_str());
... но меня интересует поведение этого в одной строке. Предположим, кто-то захотел сделать (сомнительный) макрос:
#define make_temporary_cstr(x) (static_cast<std::ostringstream&>(static_cast<std::ostringstream&>(std::ostringstream()) << x).str().c_str())
// ...
f(make_temporary_cstr("Value: " << 5));
Будет ли эта функция ожидаться?