[英]Can a constexpr function call a function that returns void?
This is what I would like to do: 这是我想做的:
void g() {
std::cout << "smth1" << std::endl;
std::cout << "smth2" << std::endl;
}
constexpr bool f() {return g(), true;}
The compiler ( gcc
version 4.8.2) is not happy with this, since g
is not constexpr
. 编译器( gcc
版本4.8.2)对此不满意,因为g
不是constexpr
。 Is it possible to get around this problem? 有可能解决这个问题吗?
The point of constexpr is that it can be fully expanded at compile-time. constexpr的要点是它可以在编译时完全扩展。 There is no possible way that the compiler can put runtime side effects (using cout
) into what is effectively a more complex compile-time constant. 编译器不可能将运行时的副作用(使用cout
)放入实际上是更复杂的编译时常量的方式。 Put another way: No actual function call will be made at runtime for constexpr
functions! 换句话说,在运行时不会对constexpr
函数进行实际的函数调用!
Luckily the solution is easy! 幸运的是,解决方案很简单!
Change f
to constexpr bool f() { return true;}
将f
更改为constexpr bool f() { return true;}
and your conditional to: 并且您的条件是:
g();
if(f())
{
// ...
}
Any evaluation of a function called during the evaluation of a constant expression must not have any side effects. 在常量表达式的求值过程中对函数的任何求值都不得有任何副作用。 In C++11, the rules are actually much stricter, allowing only a single return
statement as function body but that's not relevant to this question. 在C ++ 11中,规则实际上要严格得多,只允许将一个return
语句用作函数体,但这与该问题无关。
The compiler is not entitled to remove any code from a constexpr
function in order to make it comply. 编译器无权从constexpr
函数中删除任何代码以使其合constexpr
。 It is your responsibility to not write such code in the first place. 您有责任不首先编写此类代码。
However, it is okay to have code with side effects inside a constexpr
function if the control flow during static evaluation never passes through it. 但是,如果静态评估过程中的控制流从不通过constexpr
函数,则可以在constexpr
函数中包含具有副作用的代码。
This is valid C++11. 这是有效的C ++ 11。
void g() { std::cout << "hello, world" << std::endl; }
constexpr bool f(const bool p = false) { return p ? (g(), false) : true; }
And you may call f
like this. 您可以这样称呼f
。
constexpr auto x = f(); // ok
Because p
is false
at compile-time, the compiler need not evaluate the call to g
. 由于p
在编译时为false
,因此编译器无需评估对g
的调用。 At run-time, you may call f
with either argument just as if it were not a constexpr
function. 在运行时,您可以使用任意一个参数调用f
,就像它不是constexpr
函数一样。
f(false); // ok
f(true); // ok, produces output at run-time
What you cannot do is evaluate it in a constant expression with the parameter set to true
. 您不能做的是使用参数设置为true
的常量表达式对其求true
。
constexpr auto x = f(true); // compile-time error
Of course, this example is contrived beyond any restrictions and you should simply write 当然,此示例是人为设计的,您应该编写
constexpr bool f() noexcept { return true; }
or use a variable 或使用一个变量
constexpr auto toggle = true;
if this is all you need. 如果这就是您所需要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.