在宣布使用时,为什么需要使用include?

时间:2015-06-29 08:51:43

标签: c++ string include std using

我正在学习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#)这是不是有道理为什么你被允许创建一个字符串对象但不打印它?

谢谢!

2 个答案:

答案 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>即可。

但是,这种猜测最终没有什么区别。这就是全部:投机。最终你的代码格式不正确,因为你没有遵循标准的规则,幸好在这种情况下可以轻松解决。