多分私は何かを見逃しましたが、ヒントは見つかりません:constexpr-ifと同等のC++ 17のconstexpr三項演算子はありますか?
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;
};
いいえ、constexepr
条件演算子はありません。しかし、全体をラムダでラップしてすぐに評価することもできます(an [〜#〜] iife [〜#〜] ):
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;
};
それはこれまでで最もセクシーなコードではないかもしれませんが、それは仕事を成し遂げます。ラムダは N4487 および P017 の時点で可能な限りデフォルトでconstexpr
であることに注意してください。
_if constexpr
_はパフォーマンスの最適化であるという信念の下で行動しているようです。それはではないです。定数式を_?:
_句に入れると、使用する価値のあるコンパイラは、それが何に解決されるかを理解し、条件を削除します。したがって、記述したコードは、特定のMode
の場合、ほぼ確実に単一のオプションにコンパイルされます。
_if constexpr
_の主な目的は、他のブランチを完全に排除することです。つまり、コンパイラーは構文的にvalidであるかどうかを確認することさえしません。これは、あなたがif constexpr(is_default_constructible_v<T>)
である場合に当てはまり、それがtrueの場合はT()
を実行します。通常のif
ステートメントでは、T
がデフォルトで構成可能でない場合、if
句が周囲にある場合でも、T()
は構文的に有効なコードである必要があります定数式です。 _if constexpr
_はその要件を削除します。コンパイラーは、他の条件にないステートメントを破棄します。
式のタイプは2つの値のタイプに基づいているため、これは_?:
_ではさらに複雑になります。そのため、どちらか一方が評価されない場合でも、両方の式は正しい式である必要があります。 _?:
_のconstexpr
形式は、コンパイル時に取得されない代替案をおそらく破棄します。したがって、式のタイプは実際にはそのうちの1つにのみ基づいている必要があります。
それは非常に異なる種類のことです。