Следующее невозможно:
std::string s = boost::format("%d") % 1; // error
Вы должны явно вызвать метод str ():
std::string s = (boost::format("%d") % 1).str(); // OK
Это был бы только синтаксический сахар, но почему бы просто не добавить преобразование?
Это не очень хорошая вещь, если неявное преобразование может генерировать исключения. Преобразование в строку по умолчанию вызовет исключение, если в аргумент будет передано меньше аргументов. format
чем нужно.
Например.
std::string f()
{
boost::format fmt("%d");
// forgot to feed an argument
std::string s = fmt; // throws boost::io::too_few_args
widget.set_title( fmt ); // throws boost::io::too_few_args
return fmt; // throws boost::io::too_few_args
}
Такие неявные преобразования затрудняют поиск и анализ частей кода, которые могут генерировать исключения. Но явный .str()
вызовы предоставляют подсказку о таких возможных исключениях, которая облегчает жизнь при обеспечении безопасности исключений окружающего кода, а также (в данном конкретном случае) подсказку перепроверить предыдущий код, чтобы предотвратить возникновение указанного исключения в первую очередь.
Я думаю, что причина этого такая же, как std::stringstream
в этом контексте вы также должны использовать .str()
преобразовать поток в строку и то же самое для boost::formatter
и причина как:
std::string s1 = "Hello ", s2 = "World";
format("%s.") % s1 + s2;
Сейчас если boost::formatter
был неявно конвертируемым в std::string
тогда он производит «Hello .World», потому что format("%s.") % s1
будет преобразован в «Привет». и тогда он будет неявно преобразован в std::string
и использовать operator+
добавить это с s2
, но, вероятно, большинство программистов хотят иметь «Hello World». и это будет источником ошибки, путаницы. Но в случае, если неявного преобразования не существует, компилятор сгенерирует ошибку для этого (потому что нет operator+
за boost::formatter
а также std::string
) и для вас исправить это либо как format("%s.") % (s1 + s2)
или же str( format("%s.") % s1 ) + s2