【问题标题】:Create constrexpr function with macro behaviour创建具有宏行为的 constrexpr 函数
【发布时间】:2024-01-13 11:21:01
【问题描述】:

我有一个宏功能,可以按您的预期工作:

#define PRECONDITION(testBool) ( !(testBool) ?              \
    ( fprintf(stderr, "%s:%i: Precondition '%s' failed.\n", \
              __FILE__, __LINE__, #testBool),               \
      exit(1) ) : void(sizeof(0)) )

这很棒,因为我可以创建很好的断言:

PRECONDITION(5 > 6); // prints "<file>:<line>: Precondition '5 > 6' failed."

虽然这可行,但我正在尝试学习一种更好、更现代的方法, 使用constexpr,所以我可以有类型安全,使用std::err &lt;&lt;。 但是,我无法找到说明如何执行此操作/是否执行此操作的来源 实际上是可能的,所以我在这里问。我的形象是这样的:

constexpr void PRECONDITION(bool testBool)
{
    if(testBool) { return; }
    std::cerr << __SOME_MAGIC__ << ":" << __SOME_MAGIC__ << ":"
        << "Precondition '" << __SOME_MAGIC__ << "' failed." << std::endl;
}

是否有可能实现这种行为?

【问题讨论】:

  • constexpr 是可行的。您必须在 c++20 中等待 this 才能避免宏魔法。
  • 可能重复:*.com/q/36851551/3233393
  • 您可以使用 C++20 功能或一些 GCC 扩展来获取文件和行信息,但我认为没有办法将参数作为字符串获取。
  • 您在寻找什么“类型安全”?宏中的代码要求!(testBool) 可转换为bool。如果不是,代码将无法编译。当然,您可以在该宏中使用std::cerr 而不是fprintf。是的,人们不鼓励使用宏,但你既定的目标都不需要这样的改变。

标签: c++ c++11 macros constexpr


【解决方案1】:

简答:不。

长答案: 宏扩展只是源代码的文本转换。一旦被宏定义转换,源代码就被“提供”给编译器来编译它。因此,宏在编译器开始执行其工作之前就已展开,而constexpr 函数在编译时执行。因此,宏和constexpr 表达式是两种不同的东西。

【讨论】:

  • 我猜这暗示着,同样遵循@cigien 的评论,使用 C++20 我们可以为__FILE____LINE__ 提供替代方案,但可能永远不会为#testBool 提供替代方案。不过,感谢您的澄清!
最近更新 更多