为什么数字类型只有`to_string()`?

时间:2017-04-13 20:11:55

标签: c++ string c++11 tostring

我刚才知道C ++在<string>中定义了std::to_string()。现在我想知道为什么to_string()仅适用于数字类型。有什么特别的原因,为什么没有更普遍的

template <typename T>
std::string to_string(const T& t);

可以像这样实施:

template <typename T>
std::string to_string(const T& t) {
    std::ostringstream s;
    s << t;
    return s.str();
}

我怀疑这样的一般to_string不存在,因为很容易编写自己的to_string(),但同样的论点适用于int double,{{1}等等。

2 个答案:

答案 0 :(得分:4)

由于std::to_string()要求。

正如标准所述:

  

string to_string(int val);

     

string to_string(unsigned val);

     

string to_string(long val);

     

string to_string(unsigned long val);

     

string to_string(long long val);

     

string to_string(unsigned long long val);

     

string to_string(float val);

     

string to_string(double val);

     

string to_string(long double val);

     

返回:每个函数返回一个包含该字符的字符串对象   表示将由其生成的参数的值   使用格式说明符“%d”,“%u”调用sprintf(buf,fmt,val),   “%ld”,“%lu”,“%lld”,“%llu”,“%f”,“%f”或“%Lf”分别,   其中buf指定一个足够大小的内部字符缓冲区。

编写一个可以确定需要用于std::sprintf的说明符的模板化函数会使事情变得不必要地复杂化。

答案 1 :(得分:3)

只想添加Gill Bates answer我在this proposal中找到的内容(感谢@DAle的链接)。

该提案是关于添加通用to_string方法。他们当然是在讲一个真正的通用方法,但原理与我天真的几乎通用的方法相同:在引擎盖下,流用于从任何可以流式传输的对象中获取字符串。

由于提案是在c ++ 11之后提出的,添加这样的方法会影响现有的to_string以及他们写的“对标准的影响”一节:

  

[...]旧的和新的功能可以共存,依赖于过载   决定在a的情况下更喜欢非模板化(现有)版本   匹配参数类型。但是,可能会出现兼容性问题   一些不同但可隐式转换的参数类型的情况:

to_string(0);     // before: calls to_string(int), now: calls to_string(int)
to_string(false); // before: calls to_string(int), now: calls to_string<bool>(bool&&)
to_string('0');   // before: calls to_string(int), now: calls to_string<char>(char&&)
     

虽然前两种情况的效果相同(结果是   总是“0”),在最后一个结果将从“48”改变   (假设ASCII编码)为“0”。有几种方法可以处理   有问题的专业化案例如下:

然后他们列出了一些选项(包括忽略问题),其中没有人会真正满足。 Imho遗憾的是to_string因为它首先成为了标准。另一方面,Gill Bates的回答给出了一个很好的理由,说明为什么它从一开始就不是通用的(如果它应该生成字符串,好像sprintf被使用它一般都是微不足道的,也许是不可能的。) / p>