Witam. Jakie typy danych w podanym szablonie dopuści kompilator i dlaczego?
#include
class X {};
class Y : public X {};
template
class A {
public:
A() {}
public:
virtual T b(T x) = 0;
};
template
class B : public A {
public:
X b(T x) { return x; };
};
int main(void) {
B<???> x;
x.b(/*co tutaj?*/);
return 0;
}
Jakie typy dopuści to zależy od tego, jakich operatorów i metod używasz. Podczas kompilacji kompilator utworzy nowe klasy podmieniając szablon na daną klasę i próbuję skompilować, dlatego też klasy szablonowe muszą być w jednym pliku kompilowanym razem z użyciem tej klasy.
Wydaje mi się że dopuści tam akurat wszystko, co da się zrzutować do X (np. klasa X i Y, w tym przypadku).
U mnie (g++ 4.7) B działa bez problemu, ale próba użycia B kończy się na:
test_cpp.cpp: In instantiation of ‘class B’:
test_cpp.cpp:21:10: required from here
test_cpp.cpp:17:6: error: invalid covariant return type for ‘X B::b(T) [with T = Y]’
test_cpp.cpp:11:15: error: overriding ‘T A::b(T) [with T = Y]’
Wniosek: typ zwracany przez przeciążoną metodę musi być dokładnie taki sam jak metody bazowej. Ale jak się już stworzy obiekt klasy B, to do metody b można przekazać argument dowolnego typu, na podstawie którego da się stworzyć obiekty klasy X. Specjalnie nie mówię o rzutowaniu, bo coś takiego też działa:
class X {
public:
X() {}
X(int) {}
};
template
class A {
public:
A() {}
virtual T b(T x) = 0;
};
template
class B : public A {
public:
X b(T x) { return x; };
};
int main() {
B b;
b.b(5);
return 0;
}