さまざまなおもちゃの問題を解くことで、メタプログラミングに精通してきました。ここで私が困惑したのは、整数型引数のサイズをビット単位で提供するメタプログラムを作成する方法です。特に、 CHAR_BITやその他のマジック ナンバーを使用せずに実行したいと考えています。
次の非メタプログラムから始めました。
template <typename T>
int sizeInBits(void) {
T flag = 1;
int count = 0;
while (flag != 0) {
flag <<= 1;
++count;
}
return count;
}
メタプログラムに変換すると、次のようになると思いました。
template<typename T, int COUNT = 0, T FLAG = 1>
struct SizeInBits {
enum {Result = SizeInBits<T, COUNT + 1, FLAG << 1 >::Result};
};
template<typename T, int COUNT>
struct SizeInBits<T, COUNT, 0> {
enum {Result = COUNT};
};
ただし、このプログラムはコンパイルに失敗します。これは、テンプレート パラメーターの型を持つ非型のテンプレート パラメーターを特殊化することは明らかに違法であるためです。そのため、gcc 4.6 を使用して次のエラー メッセージが表示されます。
error: type ‘T’ of template argument ‘0’ depends on a template parameter
何か案は?
編集:
私は基本的に、とのマジックナンバーに相当するメタプログラムを探してい<climits>
ます<limits>
。したがって、たとえば、私は自分のシステムSizeInBits<char>::Result
に与えたいと思います。8
SizeInBits<unsigned>::Result
32
符号付き型での左ビット単位シフト演算子の有効性に関する注意:
コメントではFLAG << 1
、オーバーフローが発生したときに符号付き型に対して が定義されているかどうかについて懸念がありました。この投稿で引用されている C++03 標準によると、それは定義されており、上記のアルゴリズムが期待することを実行します。