关于C#:为什么std :: fstream类不采用std :: string?

关于C#:为什么std :: fstream类不采用std :: string?

Why don't the std::fstream classes take a std::string?

这虽然不是一个设计问题,但看起来确实如此。 (好吧,这是一个设计问题)。我想知道的是为什么C std::fstream类在其构造函数或打开方法中不使用std::string。每个人都喜欢代码示例,因此:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#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吗?


通过使用C字符串,C 03 std::fstream类减少了对std::string类的依赖。但是,在C 11中,std::fstream类确实允许为其构造函数参数传递std::string

现在,您可能想知道为什么没有从std:string到C字符串的透明转换,因此,期望C字符串的类仍然可以使用std::string,就像期望std::string可以接受C字符串。

原因是,这将导致转换周期,进而可能导致问题。例如,假设std::string将可转换为C字符串,以便您可以将std::string s与fstream s一起使用。还假设C字符串可以像当前标准中的状态一样转换为std::string s。现在,考虑以下内容:

1
2
3
4
5
6
7
8
9
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()

进行的操作。


C标准委员会在很多地方并没有真正优化标准库中设施之间的交互。

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

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

也是如此

我希望所有这些小问题都将在即将到来的标准中得到解决。


也许这是一个安慰:所有fstream都已打开(字符串const


n


@ Bernard:
Monoliths" Unstrung。" "一劳永逸,一劳永逸"对于火枪手来说可能有用,但对于班级设计者而言,效果却差强人意。这不是一个完全不是示例性的示例,它说明了当设计变成过度设计时,您可能犯错的严重程度。不幸的是,该示例是从您附近的标准库中提取的...
?http://www.gotw.ca/gotw/084.htm


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和字符串流。尽管已经做出了一些努力来桥接不同的部分(例如,向C库添加了重载,因为C支持重载;向basic_string添加了迭代器;向iostream迭代器适配器添加了),但是当您使用看细节。

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


n


n


我认为这是经过深思熟虑的,并且可以避免依赖。即,#include 不应强制将其包含在#include

中。

说实话,这似乎是一个无关紧要的问题。更好的问题是,为什么std :: string \\的界面这么大?


STL中是否有任何采用字符串的类……我不这么认为(无法在我的快速搜索中找到任何类)。因此,可能是一些设计决策,即STL中的任何类都不应该依赖于任何其他STL类(对于功能而言,这不是直接需要的)。


推荐阅读