以标准方式在源中指示C++标准

Bjo*_*ren 7 c++ compilation c++11

符合标准的C++编译器定义了一个__cplusplus宏,可以在预处理期间检查该宏以确定正在编译文件的标准,例如:

#if __cplusplus < 201103L
#error "You need a C++11 compliant compiler."
#endif

#include <iostream>
#include <vector>

int main(){
    std::vector<int> v {1, 2, 3};
    for (auto i : v){
        std::cout << i << " ";
    }
    std::cout << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  • 是否有标准方法来指示应该使用哪个标准编译源文件?

这将允许构建工具在编译之前检查源,以确定适当的参数-std=(参见 shebang,它可以指示脚本语言/版本:) #!/usr/bin/env python3.

我能想到的非标准和脆弱的方法是寻找预处理器检查__cplusplus但在上面的例子中我也可以写:

#if __cplusplus <= 199711L
#error "You need a C++11 compliant compiler."
#endif
Run Code Online (Sandbox Code Playgroud)

因此,编写例如正则表达式会变得非常棘手以捕捉所有变化.

编辑:

虽然我同情@Gary的答案,建议依赖于构建系统,但它假设我们实际上将有一个构建步骤.

但你今天已经可以了:

  • 使用解释器使用例如CINT运行C++程序
  • 或者使用源代码来使用例如rosecompiler进行翻译

我的问题还在于表明源代码是C++以及它的目的是什么版本(想象有人在70年后挖掘出我的代码,当时C++可能像Cobol今天那样受欢迎).

我想我想要的相同的东西是HTML的C++ equiavlent: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

Gar*_*ary 3

C++ 标准在某种程度上有点像针对库进行开发。从这个意义上说,库通常以一种缓慢弃用旧函数同时访问新函数的方式发展。典型的方法是引入新方法或签名,同时仍然允许访问旧方法或签名。

举个简单的例子,例如,您可以为 iPhone 制作一个向后兼容 IOS 4 及更高版本的应用程序。您无法选择要支持的特定版本。这很好,因为否则您将打开代码进化到可能性矩阵,使您的代码更难以理解和维护。

或者,您可以引入预处理器指令,根据某种版本或标志有条件地构建某些片段。然而,这些都是临时措施,应该随着代码的发展而删除。

因此,我认为要按原样回答这个问题,更好的问题是在这种情况下问自己,添加这样的东西实际上会解决什么问题,并且会增加不必要的复杂性(其中一个代码有不良设计的味道)?

在这种情况下,根据经验,我个人认为你最好坚持一个标准。我认为您会发现尝试通过使用各种预处理器 #ifdef 和 #ifndefs 来区分标准将使您的代码库难以理解和管理。即使您有一个包含文件,其中定义了允许所有其他文件包含的版本,它也会成为另一个需要管理的文件......更不用说当您更改它时,您必须重新编译包含它的所有内容。

如果您担心有人使用错误的标准构建您的代码库,请使用不需要开发人员输入该信息的构建系统。例如Make、Ant、cmake。它使软件的构建变得简单,并清楚地定义了如何以可重复的方式编译项目。如果您走这条路,您会发现尝试保护代码不被错误编译就不再是问题了。

另外,如果他们不遗余力地使用错误的标准进行编译,他们将会遇到大量的编译器错误 =)