我们有一个大小合理的 C++ 应用程序,但在现阶段已经相当旧了,因此它有一些怪癖。
这些怪癖之一是它如何处理使用预标准化标准库的 C++ 编译器。 有一个头文件应该可以解决符合标准的编译器和不符合标准的编译器之间的任何差异。 由于各种原因,我们不能/不想停止支持这个编译器。
#include <vector>
#include <set>
#if defined(NO_STD_LIB)
#include <iostream.h>
#else
#incude <iostream>
using std::string;
using std::cout;
using std::vector;
using std::cout;
#endif
您可以按如下方式使用它
#include stl.h
int main() {
vector<string> foo;
.....
return 0;
}
这种方法有两个主要问题:
我真的很想将这两点作为代码清理项目的一部分来解决。 第一个确实是这样做的更重要原因。
由于我们必须支持这个旧的编译器,所以我们的代码将始终必须避免与它在标准库中公开的内容发生冲突,因此第 2 点并不真正相关,尽管我希望看到一个在以下情况下有效的解决方案: / 如果我们最终可以放弃对它的支持。
到目前为止,我的想法是将超级标头分解为一组较小的标头。 例如stl_vector、stl_iostream、stl_set 等。这样我们就可以只包含我们感兴趣的标准库部分。这些文件名遵循 std 标头的模式,但具有易于搜索的前缀。 因此,当需要转储有问题的编译器时,搜索前缀并将其删除会很简单。
我认为这将很容易解决问题 1。
我真正的问题是解决问题 2。我想做这样的事情
#if defined(NO_STD_LIB)
#include <iostream.h>
#define std
#else
#include <iostream>
然后我们可以编写如下代码:
#incude "stl_iostream"
int main() {
std::string foo("bar");
std::cout << foo << std::endl;
}
这几乎奏效了。 在没有标准命名空间的地方,#define std 使 std::string 分解为 ::string,生活很美好。
然后我用一个 .cc 文件尝试了这个,该文件使用了可怕的“using namespace std;”我得到一个编译错误,因为它变成了“使用命名空间”,所以这显然是行不通的。
现在显然我可以禁止人们编写“using namespace std;”,但尽管在标头中应该避免这样做,但它有时在大量使用大量 STL 类的 .cc 文件中很有用。
最后,回答这个问题。 是否有处理这个问题的标准习惯用法。 或者,如果没有标准方法来处理这个问题,那么您使用什么技巧来支持使用预标准标准库的编译器。
我想过使用预编译头来解决编译速度问题,但我们针对不同的编译器,并且在所有编译器上实现此工作的努力可能意味着不值得我们花时间这样做。
建议我放弃不合格编译器的答案可能很受欢迎,但不会被接受,因为这是我们现在不能做的事情。
你可以尝试:
#if defined(NO_STD_LIB)
namespace std {
using ::string;
using ::cout;
using ::vector;
using ::cout;
}
#endif
然后
std::string
就可以了。
如果语言中存在
using namespace ::;
指令那就更好了;然而事实并非如此。