2015-07-18 11 views
7

consideri questo esempio (minimizzato):Definizione funzioni per il modello out-of-line utente

template <typename Descriptor> 
class hash_table 
{ 
public: 
    typedef int value_type; 

    template <typename Argument, int Callback (value_type *, Argument)> 
    void traverse (Argument); 

    template <int Callback (value_type *)> 
    void traverse_void(); 
}; 

ho definita una classe template che ha funzioni utente modello con parametri non-type. Si noti che Callback dipende da value_type typedef. Ora voglio definire le funzioni:

template <typename Descriptor> 
template <typename Argument, int Callback (typename hash_table <Descriptor>::value_type *, Argument)> 
void hash_table <Descriptor>::traverse (Argument) {} 

template <typename Descriptor> 
template <int Callback (typename hash_table <Descriptor>::value_type *)> 
void hash_table <Descriptor>::traverse_void() {} 

Ottengo errori incoerenti dai compilatori. Il risultato non dipende dalle opzioni, specificando la versione di standard C++ (vale a dire, lo stesso per C++ 98, C++ 11 e C++ 14), ma dipende dal compilatore.

GCC 6.0.0 (trunk recenti, così come molte altre versioni) accetta questo codice.

Clang 3.7.0 (tronco recente) dà il seguente errore:

test.cc:18:31: error: out-of-line definition of 'traverse_void' does not match any declaration in 'hash_table<Descriptor>' 
void hash_table <Descriptor>::traverse_void() {} 
           ^~~~~~~~~~~~~ 
1 error generated. 

EDG (Intel C++ Compiler v 15.0.3.) Dà due errori:

test.cc(15): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse<Argument,Callback>(Argument)" (declared at line 7) 
    void hash_table <Descriptor>::traverse (Argument) {} 
           ^

test.cc(19): error: declaration is incompatible with function template "void hash_table<Descriptor>::traverse_void<Callback>()" (declared at line 10) 
    void hash_table <Descriptor>::traverse_void() {} 
           ^
compilation aborted for test.cc (code 2) 

Qual è il previsto comportamento (secondo lo standard)? Se il codice è sbagliato, come posso correggere le definizioni delle funzioni?

risposta

1

Il tuo codice mi sembra soddisfacente, non vedo alcun motivo per non compilarlo. Probabilmente un bug sui compilatori che non lo consente. Tuttavia, dal momento che [temp.param]:

A non-type template-parameter of type “array of T ” or “function returning T ” is adjusted to be of type “pointer to T ” or “pointer to function returning T ”, respectively.

Si potrebbe semplicemente passare Callback te stesso di essere una funzione puntatore a. Il comportamento sarebbe identico sotto tutti gli aspetti, con l'ulteriore vantaggio che questo codice viene compilato anche su clang.

+0

[temp.param]/p8. C'è una regolazione automatica simile ai parametri di funzione. –

+0

@ T.C. Questo è orribilmente formulato allora. Qual è il punto di enumerazione dei tipi consentiti se ne vuoi aggiungere più tardi? – Barry

Problemi correlati