ふと「ビットフィールドのビット数を template 引数で指定できるのか?」と疑問に思った。
ビット数指定に求められる要件がコンパイル時定数であることなら template 引数でもいけるはず。
そんなわけで実際にやってみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | - ! - | | | ! - ! - | | | | | | ! - ! - | | | | | | | | | ! |
|
VC++2010でもgcc4.3.0でもコンパイル&リンクが通り、実行すると次のように出力された。
Data<1>[size:4] = { 1, 0, 1 }; Data<13>[size:8] = { 2, 30, 400 }; Data<22>[size:12] = { 5000, 60000, 700000 };
問題なく指定できるようだ。
だから何だという話ではあるけども。
一度でも試したことのある人やC/C++仕様を熟知している人なら既知だと思いますが、ビットフィールドのアドレスを取得することはできません。
つまりポインタや参照を取る関数の引数に渡すこともできません。
上記のようなコードを書くと、VC++2010などではコンパイルする以前にIntelliSenseに怒られます。*1
そしてもちろんコンパイルするとコンパイルエラーになります。
ちなみに、STLの std::bitset
テンプレートクラスも値を1ビット単位で扱いますが、こちらはどうかというと…
1
2
3
4
5
6
7
8
9
10
| - | | | | ! |
|
何の問題も無くコンパイル&リンク成功して実行できます。
std::bitset<N>
クラスの非const版 operator[]
オーバロードはビットの参照を返すわけではなく、 std::bitset<N>::reference
クラスの値を返します。
このクラスが std::bitset<N>
インスタンスの特定ビットに対する操作を行うようになっています。
詳しくは bitset ヘッダを読みましょう。
例えば構造体定義のあるソースコードを解析して各メンバ値を別の構造体等へコンバートするコードを自動生成するような処理を作る場合にメンバの中にビットフィールドが含まれているとハマることがあるので気を付けましょう。
例がやけに具体的なのは気にしてはいけません。いけませんったら。