Acessando membros protegidos de subclasses: gcc vs msvc
-
10-07-2019 - |
Pergunta
No visual C ++, eu posso fazer coisas como esta:
template <class T>
class A{
protected:
T i;
};
template <class T>
class B : public A<T>{
T geti() {return i;}
};
Se eu tentar compilar este em g ++, eu recebo um erro. Eu tenho que fazer isso:
template <class T>
class B : public A<T>{
T geti() {return A<T>::i;}
};
Am eu não deveria fazer o primeiro em C ++ padrão? Ou é algo mal configurado com gcc que está me dando erros?
Solução
Isto costumava ser permitido, mas mudou em gcc 3.4 .
Em uma definição de modelo, nomes não qualificados deixará de encontrar membros de uma base dependente (tal como especificado por [temp.dep] / 3 no C ++ padrão). Por exemplo,
template <typename T> struct B {
int m;
int n;
int f ();
int g ();
};
int n;
int g ();
template <typename T> struct C : B<T> {
void h ()
{
m = 0; // error
f (); // error
n = 0; // ::n is modified
g (); // ::g is called
}
};
Você deve fazer os nomes dependente, por exemplo, prefixando-los com this->. Aqui está a definição corrigida de C :: h,
template <typename T> void C<T>::h ()
{
this->m = 0;
this->f ();
this->n = 0
this->g ();
}
Outras dicas
Eu percebi este para fora:
- C ++ Super FAQ: "Por que estou recebendo erros quando meu modelo derivada de classe usa um tipo aninhado que herda de seu modelo-base-class? "
- C ++ Super FAQ: "Por que estou recebendo erros quando meu modelo derivada de classe usa um membro que herda de seu modelo-base-class? "
Aparentemente, o primeiro exemplo não é válido C ++ e é ruim que msvc leva isso. Existem soluções postadas no C ++ FAQ Lite.
Você pode querer ler sobre de duas fases de pesquisa de nome