2012-03-26 26 views
3

std::bitsetのサイズを調べる方法はありますか?コンパイル時にstd :: bitsetのサイズを調べる方法

私は

typedef std::bitset<64> Bitset; 

を持っていると私は、インスタンスを作成せずにサイズを知りたいです。例えば。私はbitset.hにソースに見るとBitset::size

ようにそれは私には全く読めないですが、私が見つけにもかかわらず、私は思ったこれらの行

public: 
    enum {_EEN_BITS = _Bits}; 
    typedef _Bitset_base<_Bits <= 8 ? 1 
     : _Bits <= 16 ? 2 
     : _Bits <= 32 ? 4 
     : 8> _Mybase; 
    typedef typename // sic 
     _Mybase::_Ty _Ty; 

私はとき_Tyのサイズを含めることができることを、教えてください、しかし、電話をしようBitset::_Ty私はillegal use of this type as an expression

私はビットセットをtypedefする前にサイズを保存することができます知っているが、それは私が望むものではありません。

+0

ビット数は列挙型の値_EEN_BITSでなければなりませんが、標準ライブラリの実装でこの宣言がないため、チェックできません。 –

+0

@RafałRawickiですが、これはあまり移植性がないと思いますが、それは残念ながら – relaxxx

+0

です。 C++のstdライブラリは完璧ではありません。 –

答えて

7

代わりにBitset::digitsを使用してください。これはあなたのケースでは64に相当します。

EDIT:そのまま使用

template< typename T > 
struct GetSize; 

template< size_t Len > 
struct GetSize< std::bitset<Len> > 
{ 
    enum { Length = Len }; 
}; 

const size_t bitsetLength = GetSize< std::bitset<1024> >::Length; 
+0

ありがとう、しかし、私は ''数字'を取得しています: 'stdのメンバーではありません:: bitset <_Bits>' ' – relaxxx

+1

I don'標準でビットセット :: digitsについて何も指定していないと思う。 – juanchopanza

+0

さらに検討すると、MSVCで起動するのは標準でもプライベートでもないようです。 – Ylisar

2

すべてのC++標準ライブラリコンテナstd::bitsetsize()メソッドを持っています。ほとんどの場合、size()を使用すると、コンパイラによってインライン展開されるため、問題ありません。

C++ 03では、他のテンプレートをパラメータ化する場合など、使用できるパブリックメンバはありません。

size()方法は、あなたがちょうどそのよう、C++ 11でテンプレートをパラメータ化するために使用することができconstexprとして宣言されているので:

std::bitset<34> b; 
std::bitset<b.size()> bx; 

標準はまだすることができますstd::bitset<N>の任意のメンバーを定義していません。移植可能に使用する。あなたの質問にはenum {_EEN_BITS = _Bits};を定義するフラグメントがありますので、std::bitset<N>::_EEN_BITSNに等しくなければなりませんが、これはVisual Studioでのみ利用可能です。

+0

ありがとうございますが、インスタンスを作成せずに知りたい – relaxxx

+0

ありがとうございます。しかし私は私の質問への答えは、インスタンスを作成せずにサイズを得ることは不可能だと思う。 – relaxxx

2

だけラファウRawickiが彼の答えで提案する同じようstd::bitset<n>().size()を使用することは間違って判明したように、ここでは異なる解決策です。

(-O2でコンパイルした場合)離れて一時的なインスタンスを最適化するコンパイラ:

76:test.cpp  ****  int i = std::bitset<8>().size(); 
77:test.cpp  **** 
78:test.cpp  ****  std::cout << i << std::endl; 
68      .loc 1 78 0 
69 0009 C7442404  movl $8, 4(%esp) #, 
69  08000000 
70 0011 C7042400  movl $_ZSt4cout, (%esp) #, 
70  000000 
71 0018 E8FCFFFF  call _ZNSolsEi # 
+0

あなたの答えに感謝します! – relaxxx

2

はい、テンプレート引数控除が正常に動作します:

template<size_t N> char (&getBitsetSize(std::bitset<N>))[N];

使用法:sizeof(getBitsetSize(Bitset());

C++ 03の解決法、C++ 11ではRafałRawickiの答えを使用します。

+0

インスタンスを作成しないことについては、このことがあります。私はYlisarの最新の答えが良いと思う。 – juanchopanza

+0

@juanchopanza:これはインスタンスを作成しません。引数_type_と 'sizeof'は、コンパイル時にコンパイラによって決定されます。引数自体は決して評価されません。興味深い。 – MSalters

+0

それは保証されているのですか、それとも最適化に依存していますか? – juanchopanza

関連する問題