今回は指定した符合無し整数型のMSB(上位ビット)だけが1で残りが0の値を求めます。具体例を挙げると、16ビットの符合無し整数型の場合は0x8000が、32ビットの符合無し整数型の場合は0x80000000が取得できます。
引数が型になりますので、こういうのはメタ関数にするのが一番です。
0 1 2 3 4 5 6 |
template <typename T> struct msb_mask { static const T value = T(T(~T(0)) - (T(~T(0)) >> 1)); }; |
型Tに符合無し整数型以外を渡した場合は破綻してしまいます。
今回もC++98でも使えるようにこのように書きましたが、本来であればstatic_assertを使って符合無し整数型以外を指定した場合はエラーにすべきです。
今回はメタ関数だけで普通の関数は定義しません。そういうこともあって、簡単に終わりすぎてしまいますので、たまにはC++20用の定義も掲載しておきます。
0 1 2 3 4 5 6 7 8 9 |
template <unsigned_integral T> struct msb_mask { static constexpr T value = T(T(~T(0)) - (T(~T(0)) >> 1)); }; template <unsigned_integral T> constexpr T msb_mask_v = msb_mask<T>::value; |
可能な限り最初のメタ関数の原型をとどめるようにしました。なお、名前空間のstd::は省略しています。
違いは3点あります。
- constexprを使用
- テンプレート仮引数Tの型をコンセプトを用いて符合無し整数型に限定
- msb_mask_vを定義
constexprについてはとくに説明は必要ないでしょう。コンセプトは今回初めて使いましたが、上記のコードをコンパイルする際は<concepts>をインクルードする必要があります。msb_mask_vは書き方を簡略化したものになります。