如何从预处理器#if 指令调用 constexpr 函数?

Posted

技术标签:

【中文标题】如何从预处理器#if 指令调用 constexpr 函数?【英文标题】:How to call a constexpr function from a preprocessor #if directive? 【发布时间】:2020-04-04 20:20:02 【问题描述】:

我想将宏定义为字符串,然后在编译时包含基于字符串比较的代码:

#include <iostream>
#include <string_view>

constexpr bool strings_equal(char const * a, char const * b) 
    return std::string_view(a)==b;


#define FOO "bar"


int main() 
#if strings_equal( FOO, "bar") == 0
    std::cout << "got a bar!" << '\n';
#endif
    return 0;

编译
$ g++ -std=c++17 test.cpp -o my_test

给出错误:

test.cpp:12:18: error: missing binary operator before token "("
   12 | #if strings_equal( FOO, "bar") == 0
      |                  ^

编辑

看来#if 指令是否在函数内部很重要,因为如果它在函数内部,我们可以用if constexpr (...) ... 替换它但是如果#if 在函数外部,这是不可能的在文件的顶层..我忘了在我的真实代码中提到这一点。

【问题讨论】:

这不起作用 - 预处理器在编译器之前运行。静态编译时表达式由编译器完成。 我认为这是不可能的,因为预处理发生在编译之前,而预处理器对函数一无所知。 哦,来吧。我们正试图摆脱预处理器。 constexpr 是朝这个方向迈出的一步,您想在预处理器中使用它(没有充分的理由) 也许您可以提供有关实际用例的更多详细信息。即使你不能使用if constexpr,也有其他方法可以在编译时常量上进行分支。 在这个冗长的 *** QA 中,有些人成功地比较了预处理器字符串,具体取决于编译器和特定用例(任何字符串比较或列表之外):***.com/questions/2335888/… - 或者您可以考虑使用makefile 并在那里进行字符串比较 【参考方案1】:

这是不可能的。

但是你可以像这样使用 if constexpr。

#include <iostream>
#include <string_view>

constexpr bool strings_equal(char const * a, char const * b) 
    return std::string_view(a)==b;


constexpr auto FOO = "bar";

int main() 
    if constexpr (strings_equal( FOO, "bar")) 
        std::cout << "got a bar!" << '\n';
    

    return 0;

Run-able Code

【讨论】:

我接受这个答案,即使它不能解决我的真正问题(请参阅我更新的问题),因为我忘了在我的问题中提及那部分

以上是关于如何从预处理器#if 指令调用 constexpr 函数?的主要内容,如果未能解决你的问题,请参考以下文章

#if 预处理器指令并不总是崩溃

C#预处理器指令——学习

在 C# 的 #if 中使用 #define 预处理器指令是不是有效

预处理器指令

#define 预处理器指令可以包含 if 和 else 吗?

C#预处理器指令之#define/#undefine/#if/#elif/#else/#endif