为什么std :: fstream类不采用std :: string?

时间:2020-03-05 18:44:23  来源:igfitidea点击:

实际上,这不是设计问题,尽管看起来像是。 (好吧,这是一个设计问题)。我想知道的是为什么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 :: strings与fstreams一起使用。还假设C字符串可以像当前标准中的状态一样转换为std :: strings。现在,考虑以下几点:

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库,即使这意味着一些问题,例如我们提出的问题。