C++ constexpr的等价三元运算符if?
也许我遗漏了什么,但我找不到任何提示:在C++17中是否有一个与constexpr if等价的constexpr三元运算符C++ constexpr的等价三元运算符if?,c++,constexpr,c++17,if-constexpr,C++,Constexpr,C++17,If Constexpr,也许我遗漏了什么,但我找不到任何提示:在C++17中是否有一个与constexpr if等价的constexpr三元运算符 template<typename Mode> class BusAddress { public: explicit constexpr BusAddress(Address device) : mAddress(Mode::write ? (device.mDevice << 1) : (device.mDevice &
template<typename Mode>
class BusAddress {
public:
explicit constexpr BusAddress(Address device) :
mAddress(Mode::write ? (device.mDevice << 1) : (device.mDevice << 1) | 0x01) {}
private:
uint8_t mAddress = 0;
};
模板
类总线地址{
公众:
显式constexpr总线地址(地址设备):
mAddress(Mode::write?(device.mDevice否,没有constexpr
条件运算符。但您可以将整个内容包装在lambda中,并立即对其求值(an):
模板
类总线地址{
公众:
显式constexpr总线地址(地址设备)
:疯狂的{
if constexpr(模式::写入){
return device.mDevice您似乎认为如果constexpr
是一种性能优化,那么它就不是。如果在?:
子句中放入一个常量表达式,任何值得使用的编译器都会找出它的解析结果并删除该条件。因此,您编写的代码几乎肯定会编译下至单个选项,用于特定的模式
if constexpr
的主要目的是完全消除另一个分支。也就是说,编译器甚至不检查它在语法上是否有效。这将适用于if constexpr(is\u default\u constructible\u v)
的情况,如果它为真,则执行t()
。使用常规的if
语句,如果T
不是默认可构造的,T()
仍然必须是语法有效的代码,即使周围的if
子句是常量表达式。如果constexpr
删除了该要求,编译器将丢弃不在其他条件下的语句
对于?:
,这变得更加复杂,因为表达式的类型基于这两个值的类型。因此,两个表达式都必须是合法表达式,即使其中一个从未计算过。?:
的constepr
形式可能会放弃编译时未采用的替代方法。因此表达式的类型实际上应该仅基于其中一个
这是一种完全不同的东西。为方便起见,接受的答案也可以转换为模板函数:
#包括
#包括
模板
decltype(auto)constepr_if(Then&&Then,OrElse&&or_else){
如果constexpr(cond_v){
返回std::forward(然后);
}否则{
返回标准::转发(或其他);
}
}
//例子
struct ModeFalse{static constexpr bool write=false;};
struct ModeTrue{static constexpr bool write=true;};
结构A{};
结构B{};
模板
auto&&test=constexpr\u if(A{},B{});
静态断言(std::is_same_v);
静态断言(std::is_same_v);
常数A;
B B;
模板
auto&&test2=constexpr_if(a,b);
静态断言(std::is_same_v);
静态断言(std::is_same_v);
不,没有。但是如果你告诉我们更多关于你想做什么的话,我们可以建议一种解决方法。假设一个三元表达式可以是constexpr
,那么编译器将在编译时计算它(换句话说,不需要特殊的constexpr
三元运算符),这难道不好吗@qxz我认为,如果constexpr
与真正类似,那么它也具有这样一个属性,即未执行的分支将被丢弃(因此,即使该分支未编译,整个过程也会编译)。刚刚添加了一个小示例解决方法:将三元if
封装在constexpr
函数中。然后调用它来初始化类成员。我正在寻找这样一个constexpr?:
正是因为类型差异:我想移动并构造一个声明为auto
的局部变量,并使用expres的结果如果constexpr
,我不能使用常规的,而不将其包装到函数中(或iLife,请参见@Barry的答案)。我更愿意避免这种语法噪音。即使是丢弃的语句也必须在语法上有效,但不必在语义上有效(它们可以做准语法的事情,比如声明不存在的嵌套类型的变量)根据constexpr生成。因此,虽然这不是对发布版本的优化,但在条件中使用constexpr在调试版本中非常有可能是一种优化。这在复杂模板中特别有用,其中存在许多代码路径,但根据模板参数,只有一个是可能的。此类函数在过去已经被开发过当试图调试一个问题时,它是一个沉重的负担,但是使用constexpr可以大大减轻负担,而不必依赖编译器的巧妙优化功能和调试符号信息。这当然不能避免对双方进行评估,但是如果主要问题是它们的类型不同,那么它可能非常方便。是的,我同意。cons的参数texpr_if
必须格式良好,才能使其与公认的答案相反。
template<typename Mode>
class BusAddress {
public:
explicit constexpr BusAddress(Address device)
: mAddress([&]{
if constexpr (Mode::write) {
return device.mDevice << 1;
}
else {
return (device.mDevice << 1) | 0x01;
}
}())
{ }
private:
uint8_t mAddress = 0;
};