在某些情况下允许从constexpr调用非constexpr函数 [英] calling non constexpr function from constexpr allowed in some conditions

查看:121
本文介绍了在某些情况下允许从constexpr调用非constexpr函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自该问题:
如何构建用作constexpr(如assert)时行为不同的自定义宏?

我不知道为什么

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 );
}

有人可以解释标准中给出了哪些规则吗?
如WF所言:如果将结果以constexpr的形式使用,例如
模板参数,则如果条件导致对非constexpr函数的求值
进行评估,则失败。

Can someone explain which rules are given from the standard? As commented from W.F.: If result is used in constexpr term like an template parameter, it fails if condition results in evaluation of non constexpr function.

如果在constexpr术语中使用的结果是
,则在编译时直接声明 会直接抱怨。

That makes assert to complain directly while compiling if result is used in constexpr term.

推荐答案

一个 constexpr 函数意味着可以评估该值在编译时的功能。由于这对于输入 true 是可能的,因此该函数是有效的 constexpr 。请记住, constexpr 函数可以具有与常规函数相同的地址,它不必是编译时的地址,仅当用作编译时函数时(您不必

A constexpr function implies that it is possible to evaluate the value of the function at compile time. Since this is possible for the input true the function is a valid constexpr. Remember that a constexpr function can have an address just as a regular function, it does not need to be compile time, only when used as a compile time function (which you do not in your example).

constexpr 页上所述.cppreference.com / w / cpp / language / constexpr rel = noreferrer> cppreference :

As mentioned on the constexpr page on cppreference:


一个constexpr函数必须满足以下要求:

A constexpr function must satisfy the following requirements:


  • 它不能是虚拟的

  • 其返回类型必须为LiteralType

  • 每个参数必须为LiteralType

  • 至少存在一组参数值,以便可以对该函数进行调用核心常量表达式的评估子表达式(对于构造函数,在常量初始化程序中使用就足够了)(自C ++ 14起)。 (强调我的想法)

  • 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)

您的函数满足上述所有要求:它不是虚拟的,它返回文字类型,参数为文字。更有趣的是最后一个要点:至少存在一组参数值,对于该参数值,函数实际上是完全编译时。 (因此,我强调最后一个项目符号)

Your function fulfils all of the above requirements: it is not virtual, it returns a literal type, the parameter is literal. And more interestingly last bullet point: there exists at least one set of argument values for which the function is actually fully compile time. (hence my emphasis of the last bullet)

就像W.F.注释中提到的函数可以用于编译时,但只能用于有效输入,即,不会导致不是编译时间常数的子表达式的输入。因此,输入 true 将起作用,但 false 将不起作用,因为它会导致 bla 正在评估。

As W.F. mentioned in the comments, the function can be used compile time, but only for valid inputs, that is, inputs that does not lead to a sub expression that is not compile time constant. So the input true will work, but false will not since it will lead to bla being evaluated.

标准中也对此进行了说明:§10.1.5.5

This is also stated in the standard: §10.1.5.5:


对于既没有默认值也没有模板的constexpr函数或constexpr构造函数,如果不存在任何参数值,使得对该函数或构造函数的调用可以是核心常量表达式(8.20)的求值子表达式,或者对于构造函数,某个对象的常量初始化程序(6.6.2),程序格式错误,无需诊断。

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


查看示例尤其是来自标准文档。

See the examples from the standard document in particular.

这篇关于在某些情况下允许从constexpr调用非constexpr函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆