为什么std :: fstream类不采用std :: string?
实际上,这不是设计问题,尽管看起来像是。 (好吧,这是一个设计问题)。我想知道的是为什么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
吗?
解决方案
回答
STL中是否有任何需要字符串的类……我不这么认为(无法在我的快速搜索中找到任何类)。因此,可能是一些设计决策,即STL中的任何类都不应该依赖于任何其他STL类(功能并非直接需要)。
回答
在某些地方,C ++标准委员会并未真正优化标准库中设施之间的交互。
std :: string
及其在库中的使用就是其中之一。
另一个例子是std :: swap
。许多容器具有交换成员函数,但没有提供std :: swap重载。 std :: sort也是如此。
我希望所有这些小问题都会在即将到来的标准中得到解决。
回答
我认为这已经考虑到了,并且这样做是为了避免依赖。即#include <fstream>不应强制将其包含在#include <string>中。
老实说,这似乎是一个无关紧要的问题。一个更好的问题是,为什么std :: string的接口这么大?
回答
It is inconsequential, that is true. What do you mean by std::string's interface being large? What does large mean, in this context - lots of method calls? I'm not being facetious, I am actually interested.
它具有的方法超出了其实际需要,并且使用积分偏移量而不是迭代器的行为还有些不确定(因为这与库的其余部分的工作方式相反)。
我认为真正的问题是C ++库包含三个部分:它具有旧的C库,具有STL,并且具有字符串和iostream。尽管已经做了一些努力来桥接不同的部分(例如,向C库添加重载,因为C ++支持重载;向basic_string添加迭代器;向iostream迭代器适配器添加了),但是当我们使用看细节。
例如,basic_string包含的方法是标准算法的不必要重复;各种查找方法可能可以安全地删除。另一个例子:语言环境使用原始指针代替迭代器。
回答
通过使用C字符串,C ++ 03std :: fstream
类减少了对std :: string
类的依赖。然而,在C ++ 11中,std :: fstream
类确实允许为其构造函数参数传递std :: string
。
现在,我们可能想知道为什么没有从std:string到C字符串的透明转换,所以期望C字符串的类仍然可以使用std :: string,就像期望一个C字符串的类一样。 std :: string
可以接受一个C字符串。
原因是这将导致转换周期,进而可能导致问题。例如,假设std :: string
可以转换为C字符串,以便我们可以将std :: string
s与fstream
s一起使用。还假设C字符串可以像当前标准中的状态一样转换为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和C字符串之间进行转换,所以对f()的调用可能会解析为两个f()替代方法中的任一个,因此模棱两可。解决方案是通过明确指定一个转换方向来打破转换周期,这是STL选择使用c_str()进行的操作。
回答
// @伯纳德:
巨石"未串"。 "一劳永逸,一劳永逸"对于火枪手可能有用,但对于班级设计师而言,效果却不尽如人意。这是一个不完全是示例性的示例,它说明了当设计变成过度设计时,我们犯错的严重性。不幸的是,该示例是从我们附近的标准库中提取的...
〜http://www.gotw.ca/gotw/084.htm
回答
也许这是一个安慰:在C ++ 0x标准的工作草案中,所有fstream在open(char const *,...)旁边都有一个open(string const&,...)。
(有关basic_ifstream声明,请参见例如27.8.1.6)
因此,当它最终确定并实施后,就不会再受我们了:)
回答
在STL之前,流IO库已添加到标准C ++库中。为了不破坏向后兼容性,已决定避免在添加STL时修改IO库,即使这意味着一些问题,例如我们提出的问题。