有条件地在C ++标头中包含文件

时间:2019-02-06 22:13:53

标签: c++ preprocessor

我有一个引用“ nvml.h”文件的程序,以执行部分​​代码。在我的Linux机器上,这是通过在头文件中包含以下行来完成的:

#include "/usr/local/cuda/include/nvml.h"

但是,即使我的系统上不存在该文件,我也希望用户能够运行该程序。我已经对该程序进行了模块化处理,因此可以完成此操作,但是我仍然需要一些方法来检查该文件是否存在,如果不存在,请避免将其包含在头文件中。

我已经尝试过IF / DEF语句,以使其在Windows和Linux上都能正常工作

#if defined(Q_OS_UNIX)
#include "usr/local/cuda/include/nvml.h"
#else
#include "C:/Users/thisUser/nvml.h"

但是我想不出一种可以使用IF / DEF结构检查文件是否存在的方法。有什么方法可以使用C ++中的预处理器指令来实现此目的?

4 个答案:

答案 0 :(得分:2)

您应该这样做

#include "nvml.h"

在根据平台进行编译时设置包含路径:

g++ -I/usr/local/cuda/include ...

答案 1 :(得分:2)

  

但是我想不出一种可以使用IF / DEF结构检查文件是否存在的方法。有什么方法可以使用C ++中的预处理器指令来实现此目的?

从C ++ 17开始,有一个宏__has_include正是这样做的。

在C ++ 17之前,标准中没有这样的指令,尽管可能已将其作为扩展支持。编译器可能支持命令行参数以提供宏定义,这些宏定义可用于在编译之前转发检查是否存在的结果。


也就是说,对于您的特定情况,最好仅包含<nvml.h>并添加父目录以包括路径。有关详细信息,请参见编译器的手册-或使用构建系统来处理它。

答案 2 :(得分:1)

C++17 使用 __has_include 稍微简化了这一点,它提供了有条件地#include 仅当文件在系统中找到时的能力。

#if __has_include( <optional> )
#   include <optional>
#elif __has_include( <experimental/optional> )
#   include <experimental/optional>
#else
//
#endif

答案 3 :(得分:-1)

执行此操作的最佳方法是定义一个宏来驱动是否包含文件:

#if defined(USE_CUDA_NVML)
#include "/usr/local/cuda/include/nvml.h"
#else
#include "C:/Users/thisUser/nvml.h"
#endif

然后,用户可以通过定义该标志来选择加入条件功能:

gcc -DUSE_CUDA_NVML main.cpp

编辑:正如评论者所提到的,通常应避免使用绝对路径。我只是将他们留在那里,以便按照OP的要求回答问题,这是另一回事。