为什么不std :: fstream类需要一个std :: string?

这不是一个devise问题,虽然它可能看起来像。 (好吧,这是一个devise问题)。 我想知道的是为什么C ++ std::fstream类不在构造函数或打开方法中使用std::string 。 每个人都喜欢这样的代码示例:

 #include <iostream> #include <fstream> #include <string> int main() { std::string filename = "testfile"; std::ifstream fin; fin.open(filename.c_str()); // Works just fine. fin.close(); //fin.open(filename); // Error: no such method. //fin.close(); } 

这使我一直在处理文件。 当然,C ++库会尽可能使用std::string

通过使用Cstring,C ++ 03 std::fstream类减less了对std::string类的依赖。 然而,在C ++ 11中, std::fstream类确实允许为其构造函数parameter passing一个std::string

现在,你可能想知道为什么没有从std:string到Cstring的透明转换,所以需要Cstring的类仍然可以像std::string那样需要std::string可以拿一个Cstring。

原因是这会导致转换周期,反过来可能会导致问题。 例如,假设std::string可以转换为一个Cstring,所以你可以使用std::string s和fstream 。 假设Cstring也可以像当前标准中的状态一样转换为std::string s。 现在,考虑以下几点:

 void f(std::string str1, std::string str2); void f(char* cstr1, char* cstr2); void g() { char* cstr = "abc"; std::string str = "def"; f(cstr, str); // ERROR: ambiguous } 

因为可以在std::string和Cstring之间进行任何转换,所以对f()的调用可能会parsing为两个f()选项之一,因此是不明确的。 解决scheme是通过明确一个转换方向来打破转换周期,这是STLselect使用c_str()所做的。

C ++标准委员会有几个地方没有真正优化标准库中设施之间的交互。

std::string和它在库中的使用就是其中之一。

另一个例子是std::swap 。 许多容器都具有交换成员函数,但不提供std :: swap的重载。 std::sort

我希望所有这些小东西都会在即将到来的标准中得到修复。

也许这是一个安慰:在C ++ 0x标准的工作草案中,所有的fstream已经在open(char const *,…)旁边得到了一个open(string const&,…)。 (例如,参见basic_ifstream声明的27.8.1.6)

所以当它完成和实施,它不会让你了:)

streamIO库已经被添加到STL之前的标准C ++库中。 为了不破坏向后兼容性,已经决定避免在添加STL时修改IO库,即使这意味着您提出的一些问题。

@伯纳德:
巨石“Unstrung”。 “一切为了一个人”,可以为火枪手工作,但对于class级devise师来说,这种工作几乎没有效果。 以下是一个不完全示范的例子,它说明了当devise变成过度devise时,你会有多糟糕。 不幸的是,这个例子是从你附近的一个标准库中取得的…〜http ://www.gotw.ca/gotw/084.htm

这是无足轻重的,这是事实。 你是什​​么意思由std :: string的接口很大? 在这种情况下,大的意思是 – 大量的方法调用? 我并不是一个开玩笑的人,我其实很感兴趣。

它有比实际需要更多的方法,它使用积分偏移而不是迭代器的行为有点不合适(因为它与库的其余部分的工作方式相反)。

我认为真正的问题是C ++库有三个部分, 它有旧的C库,它有STL,它有string和iostreams。 尽pipe我们已经做了一些工作来弥补不同的部分(例如,C库的重载增加,因为C ++支持重载;迭代器添加到basic_string;增加了iostream迭代器适配器),但是当你有很多不一致看看细节。

例如,basic_string包含标准algorithm不必要的重复方法; 各种查找方法,可能可以安全地删除。 另一个例子:语言环境使用原始指针而不是迭代器。

C ++在小型机器上长大,而不是我们今天编写的怪物。 当iostream是新的时候,很多开发者真的关心代码的大小(他们必须把他们的整个程序和数据放到几百KB)。 因此,许多人不想拉入“大”的C ++string库。 许多甚至没有使用iostream库的代码大小相同的原因。

我们没有像现在这样的数千兆内存。 我们通常没有函数级链接,所以我们在图书馆的开发人员的支配下使用大量单独的对象文件,或者拉入大量未被调用的代码。 所有这些FUD使得开发人员远离std :: string。

那时候我也避开了std :: string。 “过于臃肿”,“过于频繁地调用malloc”等。愚蠢地使用基于堆栈的缓冲区来处理string,然后添加各种繁琐的代码以确保不会溢出。

在STL中有没有类需要一个string…我不这么认为(在我的快速search无法find任何)。 所以这可能是一些devise决定,STL中的任何类都不应该依赖于任何其他的STL类(这不是function直接需要的)。

我相信这是为了避免依赖而考虑过的, 即#include <fstream>不应强制#include <string>。

说实话,这似乎是一个相当无关紧要的问题。 更好的问题是,为什么std :: string的接口如此之大?

现在,您可以非常轻松地解决这个问题:在您的CFLAGS添加-std=c++11