7

我正在尝试编写一些最初依赖于 Boost.Regex 的可移植 C++ 库代码,然后在编译器支持它时移至 TR1,并在事情从 std::tr1 命名空间移出后最终移至 C++0x 规范到标准。这是我想用预处理器做的一些伪代码:

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

4 回答 4

10

在预处理之前,如果不依赖第三方的东西,你就无法做到这一点。autoconf通常,可以使用类似的东西来完成此操作。

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

于 2009-07-25T08:57:59.870 回答
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 或其他任何内容中定义的预处理器符号。

于 2009-07-25T08:55:52.200 回答
4

您可以使用__cplusplus宏来查看您正在使用的 C++ 版本,在下一个标准(C++1x,C++0x 不应该是)中,它将具有大于 199711L 的值

#if __cplusplus > 199711
    using std::regex;
#else
    using std::tr1::regex;
#endif
于 2009-07-25T19:51:48.153 回答
2

如果您最近遇到此问题,请更新此主题:现在可以使用 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

于 2019-12-12T17:08:42.237 回答