为什么字符串类没有<<预定义运算符(运算符<<<<<<<<<<<<<&lt

时间:2013-02-10 06:56:24

标签: c++

在我看来,定义<< operator(运算符<<)直接使用字符串比使用ostringstreams然后转换回字符串更优雅。有没有理由说c ++不能开箱即用?

#include <string>
#include <sstream>
#include <iostream>
using namespace std;

template <class T> 
string& operator<<(string& s, T a) {
    ostringstream ss;
    ss << a;
    s.append(ss.str());
    return s;
}
int main() {
    string s;
    // this prints out: "inserting text and a number(1)"
    cout << (s << "inserting text and a number (" << 1 << ")\n");

    // normal way
    ostringstream os; 
    os << "inserting text and a number(" << 1 << ")\n";
    cout << os.str();
}

3 个答案:

答案 0 :(得分:3)

Streams包含其他状态。想象一下,如果这是可能的:

std::string str;
int n = 1234;
str << std::hex;
str << n;
return str; // returns "0x4d2" (or something, I forget)

为了保持这种附加状态,字符串必须具有此状态的存储空间。 C ++标准委员会(以及一般的C ++程序员)通常不赞成过多的资源消耗,其口号是“只为你使用的东西付费”。因此,字符串类中没有额外的字段。

主观回答:是我认为std::string类设计起来很差,特别是与C ++优秀标准库的其他部分相比,并为{{{{{ 1}}只会让事情变得更糟。这是一个非常主观的意见,并随意将我视为一个狂热的疯子。

答案 1 :(得分:2)

字符串作为输出流的想法的问题是它们会变得太重。

字符串旨在“保存字符串数据”,而不是格式化某些输出。输出流具有可以被操纵的重“状态”(参见<iomanip>),因此必须存储。这意味着,当然,必须为每个程序中的每个字符串存储它,但几乎没有一个用作输出流;所以这是一个巨大的资源浪费。

C ++遵循“零开销”设计原则(或者至少没有比完全必要更多的开销)。没有不增加任何不必要开销的字符串类将严重违反此设计原则。如果是这种情况:人们会在头顶关键案件中做些什么?使用C字符串......哎哟!

在C ++ 11中,另一种方法是使用带有operator+=std::to_string附加到字符串,该字符串也可以像输出流的operator<<一样链接。如果您愿意,可以将+=to_string包装在一个很好的operator<<字符串中:

template <class Number> 
std::string& operator<<(std::string& s, Number a) {
    return s += std::to_string(a);
}
std::string& operator<<(std::string& s, const char* a) {
    return s += a;
}
std::string& operator<<(std::string& s, const std::string &a) {
    return s += a;
}

您的示例,使用此方法更新: http://ideone.com/4zbVtD

答案 2 :(得分:0)

现在很可能在时间的深处丢失,但格式化的输出总是与C中的流相关联(因为它们没有“真正的”字符串),这可能已被转移到C ++中(毕竟,C与课程)。在C中,格式化为字符串的方法是使用sprintffprintf的变体,输出到流的功能。

显然我猜想但是有人可能会认为类似于你自己,流中的这些格式化内容对于字符串来说也很棒,所以他们将流类子类化为生成一个使用字符串的字符串,因为它是“输出”

这似乎是让它尽快运行的优雅解决方案。否则,您将在流和字符串中复制格式代码。