我正在学习C ++而且我一直在坚持为什么会这样。这段代码将完美地编译和运行,但是如果我取消注释//cout << foo << endl;
它不会编译。
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
string foo = "temporary";
//cout << foo << endl;
// Pause then exit
system("pause");
return 0;
}
我通过添加:#include <string>
解决了这个问题。任何人都可以告诉我为什么这是因为我(来自C#)这是不是有道理为什么你被允许创建一个字符串对象但不打印它?
谢谢!
答案 0 :(得分:2)
当你#include <iostream>
时,它会在标题中包含它想要的任何其他标题和后果声明和定义--C ++标准不禁止它包括超过严格必要的提供所需的功能。显然,使用您的编译器/版本,#include <iostream>
还包含足够的string
相关定义,以了解sa template <
... > std::basic_string::basic_string(const char*);
构造函数({{ 1}}是std::string
typedef
的特定实例basic_string
,以便您的代码有效:
char
但是,当您前往string foo = "temporary";
时,显然没有看到匹配的定义ala foo
... template <
... > std::ostream& operator<<(std::ostream&, const basic_string<
指定如何执行流式传输:这就是编译器抱怨的原因。 >&)
的定义可能在您的operator<<
标头中,这就是为什么在流式传输<string>
之前确实需要它。
您可以通过要求编译器输出而不是删除预处理文件来自己观察,这些文件在string
扩展后显示翻译单元。您可以在项目的构建配置中的某处找到选项。
总而言之,这就是为什么有时候代码可以使用少量包含而非严格必要的代码。如果您意识到自己已经完成了这项工作,那么最好包含其他标题,确保可以移植到其他编译器和同一编译器的未来版本。
答案 1 :(得分:2)
使用字符串类,其成员,运算符重载等的§21.3[string.classes]的标准库文档需要包含<string>
。任何依赖于不同的标头,您自己的设备或其他标头包含所述相同的标准都是非标准的,除非记录它(包括<string>
)。您正在使用的插入运算符在第21.4.8.9节[string.io]中描述,但最终适用相同的规则:include <string>
。
您可以通过避免使用该插件重载来推测可能允许编译成功而不包括<string>
。也许std::basic_string
的运算符重载包含在不的方式中,只需在实现中包含<iostream>
即可。