2012-03-26 7 views
3

Gibt es eine Möglichkeit, die Größe eines std::bitset herauszufinden?Wie finde ich die Größe eines std :: bitset zur Kompilierzeit

Ich habe

typedef std::bitset<64> Bitset; 

und ich möchte die Größe kennen, ohne eine Instanz zu schaffen. Z.B. wie Bitset::size

Als ich zu den Quellen in bitset.h aussehen ist es mir völlig unleserlich, aber obwohl ich diese Zeilen

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; 

, die ich mir gefunden dachte sagen, dass _Ty Größe enthalten kann, aber wenn ich versuchen, Bitset::_Ty zu rufen ich bekomme illegal use of this type as an expression

Ich weiß, dass ich die Größe irgendwo speichern kann, bevor ich das Bitset tidefdef, aber das ist nicht was ich will.

+0

Anzahl der Bits sollte im Enum-Wert '_EEN_BITS' sein, aber ich kann es nicht überprüfen, weil ich diese Deklaration nicht in meiner Implementierung der Standardbibliothek habe. –

+0

@ RafałRawicki ist es, aber ich nehme an, das ist nicht viel tragbar, was ich brauche – relaxxx

+0

Leider. Die C++ - Standardbibliothek ist nicht perfekt. –

Antwort

7

Verwenden Sie stattdessen Bitset::digits, was in Ihrem Fall 64 entspricht.

EDIT: Wie das falsch stellte sich heraus, ist hier eine andere Lösung:

template< typename T > 
struct GetSize; 

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

gebraucht wie:

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

danke, aber ich bekomme "Ziffern": ist kein Mitglied von "Std :: Bitset <_Bits>" – relaxxx

+1

ich don ' Ich denke, der Standard gibt etwas über Bitset :: digits an. – juanchopanza

+0

Ja, bei näherer Untersuchung scheint es, dass es sowohl nicht im Standard, als auch privat ist, um in MSVC zu booten. – Ylisar

2

Wie jeder C++ Standard Bibliothek Container std::bitset hat size() Methode. In den meisten Fällen ist die Verwendung von size() in Ordnung, weil es vom Compiler eingebunden wird.

In C++ 03 gibt es kein öffentliches Element, das Sie verwenden können, z. B. beim Parametrieren anderer Vorlagen.

Da size() Methode als constexpr deklariert ist, können Sie es verwenden, um eine Vorlage in C++ 11 bis parametrisieren, einfach so:

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

Norm noch kein Mitglied der nicht definiert std::bitset<N> möglich portabel verwenden. In Ihrer Frage gibt es ein Fragment, das enum {_EEN_BITS = _Bits}; definiert, so dass std::bitset<N>::_EEN_BITS gleich N sein sollte, aber das ist nur in Visual Studio verfügbar.

+0

danke, aber ich möchte es wissen, ohne eine Instanz – relaxxx

+0

Vielen Dank. aber ich denke, die Antwort auf meine Frage ist, dass es nicht möglich ist, Größe ohne eine Instanz zu erstellen – relaxxx

2

Nur std::bitset<n>().size() verwenden wie Rafał Rawicki in seiner Antwort nahe legt.

Der Compiler wird die temporäre Instanz optimieren entfernt (wenn sie mit -O2 kompiliert):

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

danke für Ihre Antwort! – relaxxx

2

Ja, Abzug Template-Argument funktioniert:

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

Verbrauch: sizeof(getBitsetSize(Bitset());

C++ 03 Lösung, für C++ 11 benutzen Rafał Rawickis Antwort.

+0

Er hat das Problem, keine Instanz zu erstellen. Ich denke, Ylisar's aktualisierte Antwort ist besser. – juanchopanza

+0

@juanchopanza: Dies erstellt keine Instanz. Das Argument _type to 'sizeof' wird vom Compiler zur Kompilierzeit bestimmt; das Argument selbst wird nie ausgewertet. – MSalters

+0

Interessant. Ist das garantiert, oder ist es auf eine Optimierung angewiesen? – juanchopanza

Verwandte Themen