确定C ++中包含文件的编译时存在

时间:2009-07-25 08:53:16

标签: c++ c++11 boost c-preprocessor tr1

我正在尝试编写一些最初依赖Boost.Regex的可移植C ++库代码,然后在编译器支持时转移到TR1,最后从std移动到C ++ 0x规范: :tr1命名空间到std。这是我想要对预处理器做的一些伪代码:

if( exists(regex) )    // check if I can #include <regex>
{
    #include <regex>    // per TR1
    if( is_namespace(std::tr1) )   // are we on TR1 or C++0x?
    {
        using std::tr1::regex;
    } else
    {
        using std::regex;
    }
} else    // fall-back to boost
{
    #include <boost/regex.hpp>
    using boost::regex;
}

当然,所有这些都需要在预处理器指令中,但如果我知道如何实现,我不会在这里问。 :)

4 个答案:

答案 0 :(得分:10)

如果不在预处理之前依赖第三方事物,就无法做到这一点。通常,autoconf之类的东西可用于实现此目的。

他们通过生成另一个带有#define指令的头文件来工作,这些指令指示您想要使用的头/库的存在。

答案 1 :(得分:6)

你不能这样做。 C ++的预处理阶段发生在编译阶段之前,因此C ++语言条件结构无法有效地放在#include等预处理程序指令周围。

如果需要条件编译,那么使用#ifdef的方法就是这样。类似的东西:

#ifdef BOOST_BUILD
  #include "somebooststuff.h"
  using namespace boost;
#else
  #include "somestdstuff.h"
  using namespace std;
#endif

其中BOOST_BUILD是您在makefile或其他任何内容中定义的预处理程序符号。

答案 2 :(得分:4)

您可以使用__cplusplus宏来查看您正在使用的C ++版本,在下一个标准(C ++ 1x,C++0x isn't meant to be)中它将具有a value larger than 199711L < / p>

#if __cplusplus > 199711
    using std::regex;
#else
    using std::tr1::regex;
#endif

答案 3 :(得分:0)

有关此主题的更新,以防您最近遇到此问题: 现在使用C ++ 17可以实现,请使用预处理器宏__has_include()

#if __has_include("MyInclude")
#  include "MyInclude"
#  define MY_INCLUDE 1
#else
#  define MY_INCLUDE 0
#endif

详细信息在这里:

https://en.cppreference.com/w/cpp/preprocessor/include