当您声明了using时,为什么需要使用include

Why do you need to use include when you have declared a using?

本文关键字:include 为什么 声明 using      更新时间:2023-10-16

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

谢谢!

当您#include <iostream>时,由标头来包含它想要的任何其他标头以及结果声明和定义-C++标准并不禁止它包含超过提供所需功能所必需的内容。很明显,在您的编译器/版本中,#include <iostream>还包含了足够多的与string相关的定义,以知道存在template <。。。> std::basic_string::basic_string(const char*);构造函数(std::stringtypedefcharbasic_string的特定实例化),以便您的代码已知有效:

string foo = "temporary";

尽管如此,当你去流式传输foo时,它显然没有看到匹配的定义ala template <。。。> std::ostream& operator<<(std::ostream&, const basic_string<。。。指定如何执行流式处理的>&):这就是编译器抱怨的原因。operator<<的定义可能在<string>标头中,这就是为什么在流式传输string之前确实需要它。

您可以通过要求编译器输出而不是删除预处理的文件来观察这一点,这些文件显示了扩展#include后的翻译单元。您可以在项目的构建配置中找到这样做的选项。

总之,这就是为什么有时代码的包含数可能比严格需要的要少。如果你意识到你已经做到了这一点,那么最好包括其他头文件,确保可移植到其他编译器和同一编译器的未来版本。

根据§21.3[string.classes],使用字符串类、其成员、运算符重载等的标准库文档需要包含<string>。任何依赖不同的标头这样做的行为,无论是您自己的设备还是其他标头,都是非标准的,除非有文件证明它这样做(包括<string>)。您正在使用的插入运算符在§21.4.8.9[string.io]中有描述,但最终适用相同的规则:包括<string>

您可以推测通过避免使用插入器重载,在不包含<string>的情况下允许编译成功的原因。也许std::basic_string的运算符重载是以的方式包含的,而不是通过在实现中简单地包含<iostream>来实现

然而,这种猜测最终并没有什么不同。这就是一切:猜测。最终,您的代码没有形成良好的格式,因为您没有按照标准遵循规则,谢天谢地,在这种情况下,这些规则是可以琐碎地寻址的。

相关文章: