回答編集履歴
1
少し解説と別の方法を追加
answer
CHANGED
@@ -37,4 +37,28 @@
|
|
37
37
|
assert(sizeof(val2) == sizeof(uint16_t));
|
38
38
|
assert(sizeof(val3) == sizeof(uint32_t));
|
39
39
|
}
|
40
|
-
```
|
40
|
+
```
|
41
|
+
|
42
|
+
# 追記 (別解)
|
43
|
+
|
44
|
+
`std::enable_if` は関数であれば返却値の型を書く箇所に書くのが普通なのですが、型のテンプレート引数に制約を付けるにあたっては返却値というものがありませんから、ひとつ余分な型引数を用意するのはよく使われるイディオムです。 この余計な型引数は `enabler` と呼ばれています。
|
45
|
+
|
46
|
+
イディオムとして定着しているのでパターンを覚えておくだけでも十分に使えるとはいうものの、本来の使い方とは言い難い面はあり、よりわかりやすい方法としては `std::conditional` で選択するというのもひとつの案です。 これも C++11 の範囲で可能です。
|
47
|
+
|
48
|
+
```cpp
|
49
|
+
#include <cassert>
|
50
|
+
#include <cstdint>
|
51
|
+
#include <type_traits>
|
52
|
+
|
53
|
+
template<std::size_t r>
|
54
|
+
struct FitSizeVariable {
|
55
|
+
using type = typename std::conditional<r <= UINT8_MAX, uint8_t, typename std::conditional<r<=UINT16_MAX, uint16_t, typename std::conditional<r<=UINT32_MAX, uint32_t, void>::type>::type>::type;
|
56
|
+
};
|
57
|
+
|
58
|
+
template<std::size_t r>
|
59
|
+
using FitSizeVariable_t = typename FitSizeVariable<r>::type;
|
60
|
+
```
|
61
|
+
|
62
|
+
ただ、 `std::conditional` は選ばれなかった側の選択肢も評価の対象にはなるという性質があり、今回の場合は問題ありませんがメタプログラミングの道具としては少し使いづらい面はあります。
|
63
|
+
|
64
|
+
それとインデントの付け方にもよりますが、ひとつの式に詰め込む形になるので個人的には見通しが悪いように思います。
|