2009-03-14 7 views
7

Si consideri il seguente codiceCome scrivere un template std :: bitset che funziona su 32 e 64-bit

template<unsigned int N> void foo(std::bitset<N> bs) 
{ /* whatever */ } 

int main() 
{ 
    bitset<8> bar; 
    foo(bar); 
    return 0; 
} 

g ++ lamenta questo su 64 bit perché il < 8> verrà interpretato come un long int unsigned , che non corrisponde esattamente al modello. Se cambio il modello per dire unsigned long int, allora le compilazioni a 32 bit si lamentano.

Ovviamente un modo per risolvere questo problema è quello di cambiare bitset < 8> per BitSet < 8ul>, ma c'è un modo per riscrivere il parte modello in modo che che possa funzionare con qualunque sia l'interpretazione di default di un numerica è letterale?

risposta

7

Il problema non è se si scrive o meno 8u o 8. Il problema ha a che fare con il tipo del parametro template del tuo modello di funzione. Il suo tipo deve corrispondere a quello utilizzato nella dichiarazione di std::bitset. Questo è size_t secondo lo standard (sezione 23.3.5)

namespace std { 
    template<size_t N> class bitset { 
    public: 
    // bit reference: 
     ... 

L'eccezione sono dimensioni di matrice, per cui è possibile utilizzare qualsiasi tipo intero (anche bool - allora l'unico formato che può essere accettato è 1 ovviamente):

// better size_t (non-negative), but other types work too 
template<int N> void f(char(&)[N]); 

Ma in altre occasioni, i tipi devono corrispondere. Si noti che questo è vero solo per gli argomenti del template autodeduced, ma non per quelli esplicitamente dati. Il motivo è che per quelli dedotti, il compilatore cerca di capire la migliore corrispondenza tra gli argomenti del template vero e quello che deduce dalla chiamata ad esso. Molte conversioni altrimenti implicite sono allora non autorizzate. Avete la gamma completa di conversioni disponibili se si mette l'argomento esplicito (ignorando la soluzione di utilizzare size_t ora a fare il mio punto)

template<int N> void foo(std::bitset<N> bs) 
{ /* whatever */ } 

int main() { 
    bitset<8> bar; 
    foo<8>(bar); // no deduction, but full range of conversions 
} 
0

un letterale numerico deve essere interpretato come un int qualunque sia la piattaforma

+0

l'ulteriore problema è che non posso farlo modello perché allora la bitset si lamenta che il suo argomento deve essere un int unsigned –

3

Uso size_t. Quindi dice almeno il MSDN.