预处理器检查constexpr const char *函数

时间:2017-10-30 21:37:00

标签: c++ constexpr preprocessor

我正在使用新版本的库,它将其版本作为static constexpr const char*函数。我在测试时在新版本和旧版本之间切换,并希望将我的代码包装在预处理器检查中仅在6.0版本中编译

下面我模拟了库如何显示版本号以及我尝试检测它是否以'6'开头:

#include <iostream>

// This comes from a library
static constexpr const char* VersionNumber() { return "6.0"; }

// This would be my intended method of detecting the version number
static constexpr bool isVersionSix() { return VersionNumber()[0] == '6'; }

int main() {
    std::cout << "Code for any version\n";

#if isVersionSix()
    std::cout << "Additional code for version 6.0\n";
#endif

    return 0;
}

不幸的是,这是一个编译器错误:

foo.cpp:12:17: error: missing binary operator before token "("
 #if isVersionSix()

我该如何解决这个问题?在旁注中,我认为检查'6'而不是"6.0"对于SO会更容易,如果可以进行编译然后使constexpr字符串比较函数应该不是问题

2 个答案:

答案 0 :(得分:3)

  

我怎样才能解决这个问题?

选项1

您可以在运行时测试版本并调用合适的函数或使用代码块。

int main() {
    std::cout << "Code for any version\n";

    if ( isVersionSix() )
    {
       std::cout << "Additional code for version 6.0\n";
    }

    return 0;
}

选项2

如果运行时分支不是选项,则可以使用功能模板,该模板是以前版本的noop,并使用版本6.0执行。

template <bool>
void doSomething()
{
   // Do nothing
}

// Specialization of the function template
template <> void doSomething<true>()
{
   std::cout << "Additional code for version 6.0\n";
}

int main() {
    std::cout << "Code for any version\n";

    doSomething<isVersionSix()>();

    return 0;
}

答案 1 :(得分:1)

如果您可以升级到GCC 7,则可以使用if constexpr,如下所示:

#include <iostream>

// This comes from a library
static constexpr const char* VersionNumber() { return "6.0"; }

// This would be my intended method of detecting the version number
static constexpr bool isVersionSix() { return VersionNumber()[0] == '6'; }

int main() {
    std::cout << "Code for any version\n";

    if constexpr (isVersionSix()) {
        std::cout << "Additional code for version 6.0\n";
    }

    return 0;
}

live example

你可以说它甚至没有编译版本6的东西,如果你没有它,因为即使在-O0它甚至不会将"Additional code for version 6.0\n"放入已编译的程序中你改变了版本号。

但是,无论如何,您可能希望改进版本检查功能。例如,如果库转到版本7,则代码将不再起作用;您可能希望更新以检查版本是否大于6而不是等于6。但是,如果您这样做,请注意不要在版本10上遇到问题。