[C++]Ableiten von Template und virtuelle Funktion überladen [solved]

Mein Problem, stark gekürzt:
Code:
#include <stdio.h>

template<class T>
class Foo
{
  public:
      virtual void blub(const T &value) const = 0;
};

class Bar : public Foo<int*>
{
  public:
      virtual void blub(const int* &value) const
      {
	printf("\n%i\n", *value);
      }
};

int main(int argc, char **argv)
{
  Bar bar;
  const int *one = new int;
  
  bar.blub(one);
  
  return 0;
}

Gibt beim Kompilieren:
Code:
gcc main.cpp                                                                                                                                                                        
main.cpp: In Funktion »int main(int, char**)«:                                                                                                                                      
main.cpp:21:7: Fehler: Variable »bar« kann nicht als vom abstrakten Typ »Bar« deklariert werden                                                                                     
main.cpp:11:1: Anmerkung:   because the following virtual functions are pure within »Bar«:                                                                                          
main.cpp:7:18: Anmerkung:       void Foo<T>::blub(const T&) const [with T = int*]                                                                                                   
make: *** [all] Fehler 1

Warum ist blub damit nicht überladen? Wenn ich für das T stur int* einsetze kommt das selbe heraus.

mfg benediktibk

PS: Vor Lauter Sternchen und Kaufmanns-Und war es gar nicht so leicht einen gültigen Aufruf von blub zusammenzubekommen. :D
 
Zuletzt bearbeitet:
Das Problem lässt sich umschiffen, indem man Bar bei der Instanzierung auf einen Typ festlegt und nicht schon bei der Vererbung. Das ist natürlich eine unelegante Bastelei, funktioniert aber erstmal.
Code:
#include <stdio.h>

template<class T>
class Foo
{
  public:
      virtual void blub(const T &value) const = 0;
};

template<class T>
class BarTemplate : public Foo<T>
{
  public:
      virtual void blub(const T &value) const
      {
    printf("\n%i\n", *value);
      }
};

typedef BarTemplate<const int*> Bar;

int main(int argc, char **argv)
{
  Bar bar;
  const int *one = new int;
  
  bar.blub(one);
  
  return 0;
}
 
Zuletzt bearbeitet:
Woran das liegt würde ich auch gerne Wissen.

Vielleicht kennt sich hier jemand mit den Compilern genauer aus. Der Code funktionier aber:

Code:
#include <stdio.h>

template<class T>
class Foo
{
  public:
      virtual void blub(T &value) const = 0;
};

class Bar : public Foo<const int*>
{
  public:
      virtual void blub(const int* &value) const
      {
	printf("\n%i\n", *value);
      }
};

int main(int argc, char **argv)
{
  Bar bar;
  const int *one = new int(30);

  bar.blub(one);

  return 0;
}

Ich hab also lediglich für "const T" "T" eingesetzt und die Parametrisierung mit "int*" durch "const int*" ersetzt.
Ist für mich semantisch eigentlich das Gleiche, weil das T in const T doch eigentlich nur durch int* ersetzt wird und dann compiliert wird, was insgesamt, dann doch wieder const int* ergibt, genauso wie wenn ich in T einfach direkt const int* einsetze. Für den Compiler gibt es da anscheinend ein Unterschied, so dass er nicht erkennt, dass die abstrakte Methode korrekt überschrieben wird.

Wenn man in weiteren Methoden, aber kein const int* haben will, sondern nur einen int*, dann muss man das ganze wohl sowie bad_alloc machen.
 
Gestern vorm Schlafen gehen (okay, war eigentlich eher heute) ist mir auch noch eine Bastel-Lösung eingefallen: partielle Spezialisierung
Code:
#include <stdio.h>

template<class T>
class Foo
{
  public:
      void blub(const T &value) const
      {
	blubInternal(value);
      }
      
  protected:
      virtual void blubInternal(const T &value) const = 0;
};

template<class T>
class Foo<T*>
{
  public:
      void blub(const T* &value) const
      {
	blubInternal(*value);
      }
      
  protected:
      virtual void blubInternal(const T &value) const = 0;
};

class Bar : public Foo<int*>
{
  protected:
      virtual void blubInternal(const int &value) const
      {
	printf("\n%i\n", value);
      }
};

int main(int argc, char **argv)
{
  Bar bar;
  const int *one = new int;
  
  bar.blub(one);
  
  return 0;
}

Wobei mir die Methode von bad_alloc ehrlich gesagt besser gefällt. Ideal ist sie aber auch nicht, vor allem, weil ich nicht weiß warum die originale Version nicht funktioniert.

Danke für die Lösung,
benediktibk
 
Das dürfte einfach ein Bug / eine Limitation im name resolver des gcc sein. Öffne mal einen Bug bei denen mit den beiden Fällen attached.
 
Beim Bugzilla vom gcc hat sich sehr bald ein Guru gemeldet, der die Lösung des Problems parat hatte. const T &value kann auch als T const &value geschrieben werden, wobei Compiler anscheinend intern die zweite Variante verwenden. Und damit verändert sich dann der Teil des Datentyps, auf den sich const auswirkt.

Code:
#include <stdio.h>

template<class T>
class Foo
{
  public:
      virtual void blub(T const &value) const = 0;
};

class Bar : public Foo<int*>
{
  public:
      virtual void blub(int* const &value) const
      {
	printf("\n%i\n", *value);
      }
};

int main(int argc, char **argv)
{
  Bar bar;
  int *one = new int;
  *one = 1;
  
  bar.blub(one);
  
  return 0;
}

mfg benediktibk
 
Zuletzt bearbeitet:
Zurück
Oben