[decl.constexpr] .5到底是什么意思? [英] What does [decl.constexpr].5 mean exactly?

查看:112
本文介绍了[decl.constexpr] .5到底是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于constexpr函数的标准在[decl.constexpr]的第5点指出:


对于非模板,非默认constexpr函数或非模板,非默认,非继承constexpr构造函数,如果不存在参数值,则该函数或构造函数的调用可以作为核心的评估子表达式常量表达式(5.19),程序格式错误;不需要诊断。


下面继续给出以下示例:

  constexpr int f(bool b){return b?抛出0:0; } // OK 
constexpr int f(){return f(true); } //格式错误,不需要诊断

我从中得到的是带有空参数的函数列表没有诊断格式错误。这让我感到非常奇怪,以至于我怀疑我的理解是不正确的。例如,这也可能是格式错误的:

  constexpr int g(){return 0; } //格式错误? 

如果是这样,其背后的原理是什么,如果不是,那么该限定条件又意味着什么/ constexpr函数何时会格式错误?






大概下面的方法好吗?

  constexpr int h(int x){return x; } //大概还好吗? 
constexpr int l = h(42); //也可以罚款


解决方案

此规则的理由是应该至少有一个 上下文,可以在 constexpr 上下文中评估函数。例如给出:

  constexpr int f(bool b){return b?抛出0:0; } // OK 
constexpr int f(){return f(true); } //格式不正确,无需诊断

无法调用 constexpr 上下文中> f(),因为通过此函数的 all 路径都将以一个不是一个核心常量表达式



编译器必须评估 all 个可能的调用,以查看是否有任何方法该函数在 constexpr 上下文中可用。一般来说,这不容易诊断,因此该语言表示它是 form-ed-no-diagnostic-required ,即您做错了什么,但编译器无法诊断。



请注意,如果 f 的零参数重载如下:

  constexpr int f(){返回f(false); } //好的

很好,因为评估以 core-结尾常量表达式



类似地,此函数:

  constexpr int g(){return 0; } //确定

以及以下版本:

  constexpr int h(int x){返回x; } //好的
constexpr int l = h(42); //好的

很好,因为 g h 可以在 constexpr 上下文中调用。



...的措辞,如果不存在参数值以致... 可能会造成混淆,因为您已经问过 g的格式正确。但是 g 可以使用零个参数调用,换句话说,可以使用 void 个参数来调用,所以很好。 / p>

The standard on constexpr functions states under point 5 of [decl.constexpr]:

For a non-template, non-defaulted constexpr function or a non-template, non-defaulted, non-inheriting constexpr constructor, if no argument values exist such that an invocation of the function or constructor could be an evaluated subexpression of a core constant expression (5.19), the program is ill-formed; no diagnostic required.

It goes on to give the following example for this:

constexpr int f(bool b){ return b ? throw 0 : 0; }  // OK
constexpr int f() { return f(true); }               // ill-formed, no diagnostic required

What I take from this is that functions with empty argument lists are no-diagnostic ill-formed. This strikes me as extremely bizarre, such that I suspect that my understanding is incorrect. For instance, would this also be ill-formed:

constexpr int g() { return 0; }       // ill-formed?

If so, what is the rationale behind this, and if not what does the qualification mean / when does a constexpr function become ill-formed?


Presumably the following are fine?

constexpr int h(int x) { return x; }  // presumably fine?
constexpr int l = h(42);              // also fine

解决方案

The rationale for this rule is that there should be at least one context where the function can be evaluated in a constexpr context. e.g. given:

constexpr int f(bool b){ return b ? throw 0 : 0; }  // OK
constexpr int f() { return f(true); }               // ill-formed, no diagnostic required

There is no way to invoke f() in a constexpr context, since all paths through this function will end in an expression that is not a core constant expression.

A compiler would have to evaluate all possible calls to see if there is any way the function is usable in a constexpr context. This is not easily diagnosable in general, so the language says it's ill-formed-no-diagnostic-required, i.e. you've done something wrong, but the compiler can't diagnose it.

Note that if the zero argument overload of f was the following:

constexpr int f() { return f(false); }   // ok

that would be perfectly fine, since the evaluation ends in a core-constant-expression.

Similarly, this function:

constexpr int g() { return 0; }      // ok

as well as this one:

constexpr int h(int x) { return x; }  // ok
constexpr int l = h(42);              // ok

are fine, since g and h can be invoked in a constexpr context.

The wording of "... if no argument values exist such that ..." might be confusing, as you've asked about the well-formedness of g. But g can be invoked with zero arguments, or in other words, with a void argument, so it's fine.

这篇关于[decl.constexpr] .5到底是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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