【问题标题】:How to guarantee that iostream wasn't included?如何保证不包含 iostream?
【发布时间】:2020-02-21 09:00:50
【问题描述】:

#include <iosfwd> in header files and #include <iostream> only in cpp files 被认为是最佳实践。我正在尝试将大量 #include <iostream> 从标头移动到现有项目中的 cpp 文件。

有没有办法保证#include 依赖树中没有文件有#include-d <iostream>?理想情况下,编译失败,如static_assert

【问题讨论】:

  • 如果您只是需要它作为快速测试而不是永久解决方案,请打开您本地的iostream 并查看是否有类似#define _IOSTREAM_ 的内容。如果是这样,请在测试包含时使用它。
  • 在头文件中包含iostream没有任何问题。无时无刻不在发生。
  • 我认为 gcc 定义了 _GLIBCXX_IOSFWD_GLIBCXX_IOSTREAM。虽然无法与其他编译器交谈
  • 我同意 Sam 的观点,以及关于为您的平台/编译器利用 iostream 标头保护的其他建议(如果不关心可移植性)。另一个技巧是制作一个中毒的 iostream,它首先在包含搜索位置被拾取。或者只是在标题上使用grep 来查找include.*iostream
  • @SamVarshavchik:如果你是呢?许多项目都有数千个翻译单元。这就是 C++20 模块如此重要的原因。减少编译时间并不是一个不合理的问题;目前还不是 C++ 能解决的问题。

标签: c++ c++17 iostream iosfwd


【解决方案1】:

C++ 不能在语言级别上真正做到这一点。即使是 cmets 中的一些建议,例如检查 iostream 标头的属性是否已经存在,也不起作用。原因是标头不是孤立的;没有什么可以阻止 .cpp 文件包含 iostream 标头,后跟您自己的标头。检查标头中的属性会产生误报,因为它不是包含它的标头。

您的问题是关于一般依赖关系图,这不是 C++ 作为一种语言所识别的东西(至少,就标题而言)。如果你有 C++20 的模块......好吧,你不会在意,因为模块导入不会导致你试图避免的问题。

因此,任何验证您要测试的内容的尝试最终都将基于构建系统中的某些内容,而不是语言。你能做的最多的就是获得哪些头包含哪些其他头的转储,并通过一些模式匹配运行它以查找 iostream 头。

【讨论】:

猜你喜欢
  • 2013-06-16
  • 1970-01-01
  • 2010-12-23
  • 1970-01-01
  • 2011-12-22
  • 2017-05-27
  • 2019-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多