constexpr函数可以调用返回void的函数吗?

时间:2015-12-09 17:33:38

标签: c++ c++11

这就是我想做的事情:

void g() {
    std::cout << "smth1" << std::endl;
    std::cout << "smth2" << std::endl;
}

constexpr bool f() {return g(), true;}

编译器(gcc版本4.8.2)对此不满意,因为g不是constexpr。有可能解决这个问题吗?

2 个答案:

答案 0 :(得分:3)

constexpr的意思是它可以在编译时完全扩展。编译器无法将运行时副作用(使用cout)放入实际上更复杂的编译时常量。换句话说:在constexpr函数运行时不会进行实际的函数调用!

幸运的是,解决方案很简单!

f更改为constexpr bool f() { return true;}

和你的条件:

g();
if(f())
{
    // ...
}

答案 1 :(得分:1)

在评估常量表达式期间调用的函数的任何评估都不得有任何副作用。在C ++ 11中,规则实际上要严格得多,只允许一个return语句作为函数体,但这与此问题无关。

编译器无权从constexpr函数中删除任何代码以使其符合要求。您有责任不首先编写此类代码。

但是,如果静态评估期间的控制流永远不会通过constexpr函数,则可以在void g() { std::cout << "hello, world" << std::endl; } constexpr bool f(const bool p = false) { return p ? (g(), false) : true; } 函数内部使用副作用。

这是有效的C ++ 11。

f

你可以这样打电话给constexpr auto x = f(); // ok

p

因为false在编译时是g,所以编译器无需评估对f的调用。在运行时,您可以使用任一参数调用constexpr,就好像它不是f(false); // ok f(true); // ok, produces output at run-time 函数一样。

true

您不能做的是在参数设置为constexpr auto x = f(true); // compile-time error 的常量表达式中对其进行评估。

constexpr bool f() noexcept { return true; }

当然,这个例子是设计超出任何限制的,你应该简单地写

constexpr auto toggle = true;

或使用变量

wireframe

如果这就是你需要的全部。