为什么boost :: format不能直接转换为std :: string?

时间:2012-10-18 08:56:44

标签: c++ boost boost-format

以下是不可能的:

std::string s = boost::format("%d") % 1; // error

您必须显式调用方法str():

std::string s = (boost::format("%d") % 1).str(); // OK

它只是语法糖,但为什么不加上转换?

2 个答案:

答案 0 :(得分:11)

我认为其原因与std::stringstream相同,在该上下文中,您还应使用.str()将流转换为字符串,并将boost::formatter转换为相同,原因如下:

std::string s1 = "Hello ", s2 = "World";
format("%s.") % s1 + s2;

现在,如果boost::formatter可隐式转换为std::string,则会产生“Hello .World”,因为format("%s.") % s1将转换为“Hello”。然后它将隐式转换为std::string并使用operator+将其添加到s2,但可能大多数程序员都希望拥有“Hello World”。这将是一个错误的混乱源。但是在没有隐式转换的情况下,编译器会为此生成错误(因为operator+boost::formatter没有std::string)并且您要将其更正为{{1} }或format("%s.") % (s1 + s2)

答案 1 :(得分:9)

如果隐式转换可以抛出异常,这不是一件好事。如果向format提供的参数少于需要,则转换为字符串将默认抛出异常。 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
}

这种隐式转换使得很难发现和分析可能引发异常的代码部分。但是明确的.str()调用提供了一些这样的可能异常的提示,这使得在确保周围代码的异常安全时更加容易,以及(在这种特定情况下)暗示要仔细检查前面的代码以防止发生异常首先。