4

在我看来,定义 << 运算符 (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();
}
4

3 回答 3

3

流包含额外的状态。想象一下,如果这是可能的:

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

为了维持这个额外的状态,字符串必须有这个状态的存储空间。C++ 标准委员会(以及一般的 C++ 程序员)普遍反对过多的资源消耗,其座右铭是“只为你使用的东西付费”。因此,字符串类中没有额外的字段。

主观的回答是:我认为这个std::string类一开始就设计得很糟糕,特别是与 C++ 优秀标准库的其他部分相比,添加特性std::string只会让事情变得更糟。这是一个非常主观的意见,请随意将我视为一个疯狂的疯子。

于 2013-02-10T07:09:41.920 回答
2

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

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

C++ 遵循“零开销”设计原则(或至少不超过完全必要的开销)。没有一个不会增加任何不必要开销的字符串类将严重违反此设计原则。如果是这种情况:人们在开销严重的情况下会怎么做?使用 C 弦……哎呀!

在 C++11 中,另一种方法是使用operator+=withstd::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

于 2013-02-10T07:13:37.347 回答
0

现在可能迷失在时间的深处,但格式化的输出总是与 C 中的流相关联(因为它们没有“真正的”字符串),这可能已经被带到 C++ 中(毕竟,这是带有类的 C) . 在 C 中,格式化为字符串的方法是使用output-to-stream 函数sprintf的变体。fprintf

显然是我的猜想,但有人可能与您自己类似地认为,流中的这些格式化内容也可以用于字符串,因此他们将流类子类化以生成一个使用字符串作为“输出”的类。

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

于 2013-02-10T07:05:49.820 回答