2015-07-18 20 views
7

Rozważmy (zminimalizowanej) przykładem:Określenie out-of-line użytkownika funkcje szablonów

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(); 
}; 

I określonych szablonu klasy, który ma funkcje o szablon z parametrami dla danego typu. Zauważ, że Callback zależy od value_type typedef. Teraz chcę zdefiniować same funkcje:

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() {} 

Dostaję niespójne błędy z kompilatorów. Wynik nie zależy od opcji, określających wersję standardu C++ (tj. Taką samą dla C++ 98, C++ 11 i C++ 14), ale zależy od kompilatora.

GCC 6.0.0 (ostatni bagażnik, a także kilka innych wersji) akceptuje ten kod.

Clang 3.7.0 (niedawne pień) daje następujący błąd:

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 kompilator C++ v 15.0.3.) Daje dwa błędy:

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) 

Jaka jest oczekiwana zachowanie (zgodnie ze standardem)? Jeśli kod jest nieprawidłowy, w jaki sposób naprawić definicje funkcji?

Odpowiedz

1

Twój kod wygląda dla mnie dobrze, nie widzę powodu, aby go nie kompilować. Prawdopodobnie błąd w kompilatorach, które go uniemożliwiają. Jednakże, ponieważ [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.

Można przełączyć Callback się być funkcja wskaźnik do. Zachowanie będzie identyczne we wszystkich aspektach, z dodatkową korzyścią, że ten kod również kompiluje się na klang.

+0

[temp.param]/p8. Istnieje automatyczna regulacja podobna do parametrów funkcji. –

+0

@ T.C. To jest okropnie sformułowane. Jaki jest sens wyliczania dozwolonych typów, jeśli zamierzasz dodać więcej później? – Barry

Powiązane problemy