为什么在声明了 using 后还需要使用 include?

Why do you need to use include when you have declared a 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#)这没有意义为什么你被允许创建一个字符串对象但不打印它?

谢谢!

当您 #include <iostream> 时,由 header 来包含它想要的任何其他 header 和结果声明和定义 - C++ 标准不禁止它包含更多比提供所需功能所必需的要多。显然,对于您的 compiler/version,#include <iostream> 还包括足够多的 string 相关定义,以了解有一个 template <...> std::basic_string::basic_string(const char*); 构造函数(std::stringtypedefbasic_string 的特定实例化 char),因此您的代码是有效的:

string foo = "temporary";

不过,当您转到流 foo 时,它显然没有看到 template <...> std::ostream& operator<<(std::ostream&, const basic_string<...>&) 的匹配定义指定如何执行流式处理:这就是编译器抱怨的原因。 operator<< 的定义可能在您的 <string> header 中,这就是为什么在流式传输 string.

之前确实需要它的原因

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

总而言之,这就是为什么您有时可能会使用比绝对必要的更少的 include 来处理代码。如果您意识到自己已经这样做了,那么包含其他 header 总是一个好主意,以确保对其他编译器和同一编译器的未来版本的可移植性。

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

您可以推测是什么 可能 允许编译成功而不包括 <string> 通过避免使用该插入器重载。也许 std::basic_string 的运算符重载以 而不是 的方式包含,只需在您的实现中包含 <iostream> 即可实现。

然而,这种猜测最终并没有什么不同。这就是全部:投机。最终你的代码不是 well-formed 因为你没有遵循标准的规则,幸运的是在这种情况下它是微不足道的。