use*_*984 4 c++ compile-time c++11
假设我正在编写一个跨平台库,我必须以一种不同平台的不同行为的方式组织代码,这种行为(或定义)是在编译时基于我的库所在的平台选择的.被编译.
在C++中执行此操作的"通常"方法是#ifdef在编写方法或类时大量污染代码.
方法的问题是:
#ifdef由于C++ 11中有许多新功能,我想知道是否有更改内容以及是否有新选项.
您应该使用构建系统来执行此操作.您应该为标题提供与平台无关的函数声明和类的定义.然后,根据目标平台,构建系统应编译这些函数和类的适当实现.
例如,让我们考虑创建用于显示图形或GUI元素的窗口.如果您没有使用库来执行此操作,则必须自己编写跨平台代码.首先,您应该考虑与平台无关的接口应该是什么.也许你有一个window类和一些辅助函数.然后,您可以在头文件中提供该类的定义和辅助函数的声明,并为每个平台提供单独的实现.然后你会有一组像这样的文件:
window.hwindow_wayland.cppwindow_winapi.cppwindow_x11.cpp现在,所有需要使用您的类和函数的文件应该只是#include <window.h>.它们都获得相同的函数声明.但是,您在构建系统的配置中指定window_x11.cpp应在具有X11窗口系统的系统上,window_wayland.cpp在使用Wayland的系统上以及window_winapi在Windows 上进行编译.这意味着,根据您正在构建的平台,您将获得可在目标平台上运行的标头的实现.
这有几个优点:
这并不意味着使用定义来有选择地编译代码的不同部分有任何问题.我更喜欢只看到已经本地化到平台相关部分的少量代码.理想情况下,将依赖于平台的代码包装在一个函数中,然后让#ifdefs换掉实现.
具体如何进行这种选择性构建取决于您正在使用的构建系统.对于GNU构建系统,您可以使用automake实现条件编译.文档中给出了一些示例.给出一个简单的例子:
bin_PROGRAMS = hello
if LINUX
hello_SOURCES = hello-linux.c hello-common.c
else
hello_SOURCES = hello-generic.c hello-common.c
endif
Run Code Online (Sandbox Code Playgroud)
automake使用此配置运行将生成相应的makefile.