2012-09-22 13 views
15

Sto cercando di chiamare la funzione di classe A<F>::f() dall'interno classe S, ma sto ottenendo i seguenti errori quando ho istanziare un oggetto S (S<int>s) e chiamarlo è f funzione membro():Perché viene visualizzato l'errore "A <int>" non è una base accessibile di "S <int>" per la classe base di una classe base?

source.cpp: In instantiation of ' int S<F>::f() [with F = int] ':
source.cpp:30:21: required from here
source.cpp:22:25: error: ' A<int> ' is not an accessible base of ' S<int> '

Nota che questo funziona quando sostituisco return A<F>::f(); all'interno della dichiarazione di classe S con return C<A, F>::f();. Ma mi chiedo il motivo per cui non posso fare il contrario ...

#include <iostream> 

template <typename T> class A { 
    public: 
     int f(); 
}; 

template <typename T> int A<T>::f() { 
    return sizeof(T); 
} 

template <template <typename> class E, typename D> class C : E<D> { 
    public: 
     int f() { 
     return E<D>::f(); 
     } 
}; 

template <typename F> class S : C<A, F> { 
    public: 
     int f() { 
     return A<F>::f(); 
     } 
}; 

int main() { 

    S<int>s; 

    std::cout << s.f(); 

} 

ogni aiuto è apprezzato e se hai bisogno di ulteriori chiarimenti non esitate a lasciare un commento.

Aggiornamento

Da questa domanda si risolve Credo che dovrebbe inviare il codice che effettivamente lavorate:

#include <iostream> 

template <typename T> class A { 
    public: 
     int f(); 
}; 

template <typename T> int A<T>::f() { 
    return sizeof(T); 
} 

template <template <typename> class E, typename D> class C : public E<D> { 
    public: 
     int f() { 
     return E<D>::f(); 
     } 
}; 

class S : public C<A, int> {}; 

int main() { 

    S s; 

    std::cout << s.f(); // 4 

} 

risposta

30
template <typename F> class S : C<A, F> 
          ^

Non si specifica un patrimonio public, quindi il valore di default per private, rendendo le classi base inaccessibile.

+0

Non importa quale ultimo commento. Funziona ora che ho sostituito * tutte * le classi con ereditarietà pubblica. –

+0

Un'altra idea sarebbe quella di creare tutte le strutture in modo da avere ereditarietà predefinita. :) – 0x499602D2

5

Penso che sia solo una questione di usare public classe di ereditarietà. Prova con:

template <template<class> class E, typename D> class C : public E<D> { 
    public: 
     int f() { 
     return E<D>::f(); 
     } 
}; 

template <typename F> class S : public C<A, F> { 
    public: 
     int f() { 
     return A<F>::f(); 
     } 
}; 
3

Quando si sta tentando di chiamare la versione A di f() si utilizza la notazione A<F>::f(). Se A<F> avesse una funzione membro staticf(), questa funzione verrebbe effettivamente chiamata. Tuttavia, A<F> ha solo una funzione membro non staticf(), ad esempio la chiamata viene implicitamente tradotta in this->A<F>::f(). Tuttavia, S<F> non ha un A<F> come base accessibile (è una base private di C<A, F>). Dagli sguardi di esso si vuole delegare alla versione di f()C<A, F> s:

C<A, F>::f(); 

che dovrebbe funzionare a causa C<A, F> è una base accessibile di S<int> o fare la base E<D> di C accessibili, rendendo sia public o protected.

+0

Non sicuro che questo sia vero. In questo caso "A " è una base privata del tipo. La ricerca troverà il nome del tipo iniettato prima di poter controllare il livello dello spazio dei nomi, quindi se il metodo membro in 'A' è statico o meno non ha molta importanza. –

Problemi correlati