Why boost::format cannot be converted directly to std::string? [closed]
-
08-07-2021 - |
Pregunta
Following is not possible:
std::string s = boost::format("%d") % 1; // error
You have to explicitely call the method str():
std::string s = (boost::format("%d") % 1).str(); // OK
It would only be syntactic sugar, but why not just add the conversion?
Solución
It is not a very good thing if an implicit conversion can throw exceptions. Conversion to string will by default throw an exception if less arguments are fed to format
than needed.
E.g.
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
}
Such implicit conversions make it hard to spot and analyze the parts of code that can throw exceptions. But explicit .str()
calls provide a hint of such possible exceptions, which makes life easier when ensuring the surrounding code's exception safety, as well as (in this particular case) hinting to double-check preceding code to prevent said exception from happening in the first place.
Otros consejos
I think the reason for this is same as std::stringstream
, in that context you should also use .str()
to convert the stream to string and same for boost::formatter
and the reason is as:
std::string s1 = "Hello ", s2 = "World";
format("%s.") % s1 + s2;
Now if boost::formatter
was implicitly convertible to std::string
then it produce "Hello .World", because format("%s.") % s1
will be converted to "Hello ." and then it will be implicitly converted to std::string
and use operator+
to add it with s2
, but probably most programmers want to have "Hello World." and that will be a source of error an confusion. But in the case that no implicit conversion exist compiler will generate error for this(because there is no operator+
for boost::formatter
and std::string
) and for you to correct it either as format("%s.") % (s1 + s2)
or str( format("%s.") % s1 ) + s2