这就是我想做的事情:
void g() {
std::cout << "smth1" << std::endl;
std::cout << "smth2" << std::endl;
}
constexpr bool f() {return g(), true;}
编译器(gcc
版本4.8.2)对此不满意,因为g
不是constexpr
。有可能解决这个问题吗?
答案 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
如果这就是你需要的全部。