Why boost::format cannot be converted directly to std::string? [closed]
Asked Answered
T

2

12

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?

Trigger answered 18/10, 2012 at 8:56 Comment(6)
Isn't the overloading of % bad enough? :)Heirloom
I'm not sure what kind of answer you're looking for here. Are you asking if there are any semantic issues that prevent Boost from implementing such a thing? Or are you just saying, "They should have done it this way."Sybyl
I am trying to understand the semantic issues. I usually think that the boost libs are well designed.Trigger
Implicit conversions are sometimes convenient, but also cause problems by hiding bugs when you really didn't want a conversion. Boost follows the model of std::string and std::stringstream, neither of which provide implicit conversions to their content types.Sitdown
@Heirloom And what is bad in overloading '%'??Vivisectionist
@Heirloom There is a good rationale here: boost.org/doc/libs/1_51_0/libs/format/doc/choices.htmlSeptennial
O
9

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.

Overcritical answered 18/10, 2012 at 10:15 Comment(1)
Both answers (this and the one of BigBoss) give good reasons for not having the implicit conversion. But I had to accept only one :-)Trigger
V
11

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

Vivisectionist answered 18/10, 2012 at 10:6 Comment(0)
O
9

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.

Overcritical answered 18/10, 2012 at 10:15 Comment(1)
Both answers (this and the one of BigBoss) give good reasons for not having the implicit conversion. But I had to accept only one :-)Trigger

© 2022 - 2024 — McMap. All rights reserved.