C++ 为什么 std::fstream 类不采用 std::string?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32332/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why don't the std::fstream classes take a std::string?
提问by Bernard
This isn't a design question, really, though it may seem like it. (Well, okay, it's kind of a design question). What I'm wondering is why the C++ std::fstream
classes don't take a std::string
in their constructor or open methods. Everyone loves code examples so:
这不是一个设计问题,真的,虽然它看起来像。(好吧,这是一个设计问题)。我想知道的是为什么 C++std::fstream
类不在std::string
它们的构造函数或 open 方法中使用 a 。每个人都喜欢代码示例,所以:
#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();
}
This gets me all the time when working with files. Surely the C++ library would use std::string
wherever possible?
在处理文件时,这让我一直在使用。C++ 库肯定会std::string
尽可能使用吗?
采纳答案by wilhelmtell
By taking a C string the C++03 std::fstream
class reduced dependency on the std::string
class. In C++11, however, the std::fstream
class does allow passing a std::string
for its constructor parameter.
通过采用 C 字符串,C++03std::fstream
类减少了对std::string
类的依赖。但是,在 C++11 中,std::fstream
该类确实允许std::string
为其构造函数参数传递 a 。
Now, you may wonder why isn't there a transparent conversion from a std:string
to a C string, so a class that expects a C string could still take a std::string
just like a class that expects a std::string
can take a C string.
现在,您可能想知道为什么没有从 astd:string
到 C 字符串的透明转换,所以需要 C 字符串std::string
的类仍然可以像需要 a 的类std::string
可以使用 C 字符串一样。
The reason is that this would cause a conversion cycle, which in turn may lead to problems. For example, suppose std::string
would be convertible to a C string so that you could use std::string
s with fstream
s. Suppose also that C string are convertible to std::string
s as is the state in the current standard. Now, consider the following:
原因是这会导致转换周期,进而可能导致问题。例如,假设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
}
Because you can convert either way between a std::string
and a C string the call to f()
could resolve to either of the two f()
alternatives, and is thus ambiguous. The solution is to break the conversion cycle by making one conversion direction explicit, which is what the STL chose to do with c_str()
.
因为您可以在 astd::string
和 C 字符串之间转换任何一种方式,所以调用f()
可以解析为两种f()
选择中的任何一种,因此是不明确的。解决方案是通过使一个转换方向显式来打破转换循环,这正是 STL 选择对c_str()
.
回答by Christopher
There are several places where the C++ standard committee did not really optimize the interaction between facilities in the standard library.
有几个地方 C++ 标准委员会没有真正优化标准库中设施之间的交互。
std::string
and its use in the library is one of these.
std::string
它在图书馆中的使用就是其中之一。
One other example is std::swap
. Many containers have a swap member function, but no overload of std::swap is supplied. The same goes for std::sort
.
另一个例子是std::swap
。许多容器都有一个交换成员函数,但没有提供 std::swap 的重载。也是如此std::sort
。
I hope all these small things will be fixed in the upcoming standard.
我希望所有这些小事情都会在即将到来的标准中得到解决。
回答by Pieter
Maybe it's a consolation: all fstream's have gotten an open(string const &, ...) next to the open(char const *, ...) in the working draft of the C++0x standard. (see e.g. 27.8.1.6 for the basic_ifstream declaration)
也许这是一个安慰:在 C++0x 标准的工作草案中,所有 fstream 都在 open(char const *, ...) 旁边得到了一个 open(string const &, ...)。(参见例如 27.8.1.6 的 basic_ifstream 声明)
So when it gets finalised and implemented, it won't get you anymore :)
因此,当它最终确定并实施时,您将不再受用:)
回答by Drealmer
The stream IO library has been added to the standard C++ library before the STL. In order to not break backward compatibility, it has been decided to avoid modifying the IO library when the STL was added, even if that meant some issues like the one you raise.
流 IO 库已在 STL 之前添加到标准 C++ 库中。为了不破坏向后兼容性,已决定在添加 STL 时避免修改 IO 库,即使这意味着您提出的问题。
回答by swmc
@ Bernard:
Monoliths "Unstrung." "All for one, and one for all" may work for Musketeers, but it doesn't work nearly as well for class designers. Here's an example that is not altogether exemplary, and it illustrates just how badly you can go wrong when design turns into overdesign. The example is, unfortunately, taken from a standard library near you...
~ http://www.gotw.ca/gotw/084.htm
@伯纳德:
巨石“松散”。“一劳永逸”可能适用于火枪手,但对职业设计师来说几乎没有效果。这是一个并非完全示例性的示例,它说明了当设计变成过度设计时,您可能会出错的严重程度。不幸的是,该示例取自您附近的标准库... ~ http://www.gotw.ca/gotw/084.htm
回答by DrPizza
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.
这是无关紧要的,这是事实。std::string 的接口很大是什么意思?在这种情况下,大是什么意思 - 很多方法调用?我不是开玩笑,我真的很感兴趣。
It has more methods than it really needs, and its behaviour of using integral offsets rather than iterators is a bit iffy (as it's contrary to the way the rest of the library works).
它的方法比它真正需要的要多,而且它使用积分偏移量而不是迭代器的行为有点不确定(因为它与库的其余部分的工作方式相反)。
The real issue I think is that the C++ library has three parts; it has the old C library, it has the STL, and it has strings-and-iostreams. Though some efforts were made to bridge the different parts (e.g. the addition of overloads to the C library, because C++ supports overloading; the addition of iterators to basic_string; the addition of the iostream iterator adaptors), there are a lot of inconsistencies when you look at the detail.
我认为真正的问题是 C++ 库包含三个部分;它有旧的 C 库,它有 STL,它有字符串和 iostreams。虽然做了一些努力来桥接不同的部分(例如,向 C 库添加重载,因为 C++ 支持重载;向 basic_string 添加迭代器;添加 iostream 迭代器适配器),但是当您使用看细节。
For example, basic_string includes methods that are unnecessary duplicates of standard algorithms; the various find methods, could probably be safely removed. Another example: locales use raw pointers instead of iterators.
例如,basic_string 包含与标准算法不必要重复的方法;各种查找方法,可能可以安全地删除。另一个例子:语言环境使用原始指针而不是迭代器。
回答by doug65536
C++ grew up on smaller machines than the monsters we write code for today. Back when iostream was new many developers really cared about code size (they had to fit their entire program and data into several hundred KB). Therefore, many didn't want to pull in the "big" C++ string library. Many didn't even use the iostream library for the same reasons, code size.
C++ 是在比我们今天编写代码的怪物更小的机器上长大的。回到 iostream 刚出现的时候,许多开发人员真正关心代码大小(他们必须将整个程序和数据装入数百 KB)。因此,许多人不想引入“大”C++ 字符串库。出于同样的原因,代码大小,许多人甚至没有使用 iostream 库。
We didn't have thousands of megabytes of RAM to throw around like we do today. We usually didn't have function level linking so we were at the mercy of the developer of the library to use a lot of separate object files or else pull in tons of uncalled code. All of this FUD made developers steer away from std::string.
我们没有像今天那样有数千兆字节的 RAM 可供使用。我们通常没有函数级链接,因此我们受库开发人员的支配,可以使用大量单独的目标文件,否则会引入大量未调用的代码。所有这些 FUD 使开发人员远离 std::string。
Back then I avoided std::string too. "Too bloated", "called malloc too often", etc. Foolishly using stack-based buffers for strings, then adding all kinds of tedious code to make sure it doesn't overrun.
那时我也避免了 std::string 。“太臃肿”、“经常调用 malloc”等等。愚蠢地将基于堆栈的缓冲区用于字符串,然后添加各种繁琐的代码以确保它不会溢出。
回答by Jonathan Birge
Nowadays you can solve this problem very easily: add -std=c++11
to your CFLAGS
.
现在你可以很容易地解决这个问题:添加-std=c++11
到你的CFLAGS
.
回答by DrPizza
I believe that this has been thought about and was done to avoid the dependency; i.e. #include <fstream> should not force one to #include <string>.
我相信这已经被考虑过并且是为了避免依赖;即#include <fstream> 不应该强制一个#include <string>。
To be honest, this seems like quite an inconsequential issue. A better question would be, why is std::string's interface so large?
老实说,这似乎是一个无关紧要的问题。一个更好的问题是,为什么 std::string 的接口如此之大?
回答by Magnus Westin
Is there any class in STL that takes a string... I dont think so (couldnt find any in my quick search). So it's probably some design decision, that no class in STL should be dependent on any other STL class (that is not directly needed for functionality).
STL 中是否有任何需要字符串的类......我不这么认为(在我的快速搜索中找不到任何类)。所以这可能是一些设计决定,STL 中的任何类都不应该依赖于任何其他 STL 类(功能不是直接需要的)。