问题描述
来自该问题:
我不知道为什么
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 antemplate parameter, it fails if condition results in evaluationof non constexpr function.
如果在constexpr术语中使用的结果是
,则在编译时直接声明
会直接抱怨。
That makes assert
to complain directly while compiling if result isused 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:
- 它不能是虚拟的
- 其返回类型必须为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.
标准中也对此进行了说明::
This is also stated in the standard: §10.1.5.5:
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函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!