gpt4 book ai didi

c++ - 在某些情况下允许从 constexpr 调用非 constexpr 函数

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:59:38 28 4
gpt4 key购买 nike

来自那个问题: How to build a custom macro that behaves differently when used as constexpr (like assert)?

我想知道如果有条件的话为什么可以调用非 constexpr 函数。

void bla( )
{
std::cout << "bla called!" << std::endl;
}

constexpr bool check(bool condition)
{
//bla(); // can not directly be called -> not constexpr!
condition ? void (0) : bla(); // compiles and runs even if condition is true or false!

// if condition is const, it did not compile because it
// directly force execution of non constexpr function
true ? void(0): bla(); // also that compiles!, ok, directly evaluated
//true ? bla(): void(0); // that did not compile;)

//false ? void(0): bla(); // that did not compile;)
false ? bla(): void(0); // compiles, ok, directly evaluated

return 0;
}

int main()
{
check( false );
check( true );
}

有人可以解释一下标准中给出了哪些规则吗?正如 W.F. 评论的那样:如果结果在 constexpr 术语中使用,例如模板参数,如果条件导致评估则失败非 constexpr 函数。

这使得 assert 如果结果是,则在编译时直接提示在 constexpr 术语中使用。

最佳答案

constexpr 函数意味着可以在编译时评估函数的值。由于这对于输入 true 是可能的,因此该函数是一个有效的 constexpr。请记住,constexpr 函数可以像常规函数一样具有地址,它不需要是编译时的,仅当用作编译时函数时(您在示例中不需要)。

cppreference 上的 constexpr 页面所述:

A constexpr function must satisfy the following requirements:

  • it must not be virtual
  • its return type must be LiteralType
  • each of its parameters must be LiteralType
  • there exists at least one set of argument values such that an invocation of the function could be an evaluated subexpression of a core constant expression (for constructors, use in a constant initializer is sufficient) (since C++14). No diagnostic is required for a violation of this bullet. (Emphasis mine)

你的函数满足了以上所有要求:它不是虚函数,它返回一个字面量类型,参数是字面量。更有趣的是最后一个要点:至少存在一组参数值,函数实际上是完全编译时间的。 (因此我强调最后一个项目符号)

作为 W.F.评论中提到,该函数可以在编译时使用,但仅限于有效输入,即不会导致不是编译时常量的子表达式的输入。所以输入 true 会起作用,但是 false 不会,因为它会导致 bla 被计算。

这在标准中也有说明:§10.1.5.5 :

For a constexpr function or constexpr constructor that is neither defaulted nor a template, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (8.20), or, for a constructor, a constant initializer for some object (6.6.2), the program is ill-formed, no diagnostic required.

constexpr int f(bool b)
{ return b ? throw 0 : 0; } // OK

constexpr int f()
{ return f(true); } // ill-formed, no diagnostic required

具体请参阅标准文档中的示例。

关于c++ - 在某些情况下允许从 constexpr 调用非 constexpr 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47726503/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com