Si consideri il seguente codice:Perché questa dichiarazione di una funzione nella classe template non è valida?
template<int X, int Y>
struct S
{
typedef int func(int,float) const;
};
template<int X>
struct D : public S<X,6>
{
typename S<X,6>::func func;
};
template<int X>
int D<X>::func(int,float) const
{
return 1;
}
//----------------
struct W : public S<7,8>
{
S<7,8>::func func;
};
int W::func(int,float) const
{
return 2;
}
#include <iostream>
int main()
{
W w;
std::cout << w.func(1,4.3) << "\n";
D<3> d;
std::cout << d.func(1,4.3) << "\n";
}
Se commento il codice che dichiara di classe D
e D::func()
così come le linee corrispondenti nel main()
, il codice viene compilato normalmente, e vedo 2
in uscita, come previsto.
Ma quando faccio il modello di classe derivata (aggiungendo typename
prima dichiarazione di funzione, come S<X.6>
è un ambito dipendente), ottengo i seguenti errori:
test.cpp:13:27: error: no ‘int D<X>::func(int, float) const’ member function declared in class ‘D<X>’
int D<X>::func(int,float) const
^
test.cpp: In instantiation of ‘struct D<3>’:
test.cpp:32:10: required from here
test.cpp:10:27: error: field ‘D<3>::func’ invalidly declared function type
typename S<X,6>::func func;
^
- Perché non posso dichiarare
func
in una classe derivata da template, mentre nella classe non-template è OK? - Che cosa è esattamente "tipo di funzione dichiarato non valido"? cosa non è valido qui?
Ho la sensazione che ciò sia tecnicamente valido per [dcl.fct]/10 nelle specifiche, ma dichiarare una funzione con un typedef dipendente è come un caso d'angolo di un caso d'angolo: non sono sicuro se alcuni compilatori lo gestirò come ti aspetti. – TartanLlama
Direi che 'S' potrebbe essere specializzato nell'ultimo caso, quindi la definizione di' D :: func' potrebbe diventare non valida. –
Jarod42
@ Jarod42 Sembra che abbiamo bisogno di 'function_typename' così come' typename': p – TartanLlama