[C++] Template linken

Legenbaer

Cadet 4th Year
Registriert
Juni 2006
Beiträge
108
Hallo Leute,

ich sitze gerade an einem Problem welches etwas Rätselhaft ist.
Ich habe eine Template-Funktion in einem Projekt gegen das ich Linken will. Dazu will ich in dem Projekt schonmal eine Initialisierung vornehmen da er die Funktion sonst ja nich finden kann.

Header:

Code:
Namespace XY{
  class Foo {
    template<typename T>
    void function(T& o); 
  }
}

CPP:

Code:
//Instanziierung über Prototyp
void XY::Foo::function<Typ>(Typ&);

template<typename T>
void XY::Foo::function(T& o)
{
//Code
}

Wenn ich das recht verstanden habe ist das mit dem Prototypen nötig weil die Funktion Teil einer Bib ist gegen die ich Linken will.
Allerdings wirft mir der Compiler (GCC 4.3) das ganze um die Ohren. :/

Fehler: Template-ID »function<Typ>« in Deklaration des ersten Templates
Fehler: Deklaration von »void XY::Foo::function(Typ&)« außerhalb einer Klasse ist keine Definition

Hat jemand eine Idee? oO

Danke schonmal!

MfG

Baer
 
Verstehe ich das richtig, dass du mit expliziter Instanziierung arbeiten willst?

Wenn ja, dann muss die explizite Instanziierung hinter die Funktionsdefinition. Was soll der Compiler sonst instanziieren? Er kennt die Funktion ja noch garnicht. ;)

Und bist du sicher, dass du mit expliziter Instannziierung glücklich bist?

Falls du garnicht weißt wovon ich rede, sag Bescheid. Dann wäre wohl ein tiefgehender Crashkurs nötig. ^^
 
Heyho...also wenn ich die Instanziierung hinter die Funktion schreibe ändert sich leider auch nichts. Wie gesagt... ich muss es ja machen weil ich gegen die Library ja linken will. Wenn ich nicht expliziet instanziiere kann die Lib auch keine Funktion besitzen sie auf eine bestimmte Klasse passt.
 
Also so compiliert dein Code:

Code:
namespace XY{
  class Foo {
    template<typename T>
    void function(T& o); 
  };
}

Code:
namespace XY {
  template <typename T>
  void Foo::function(T& o)
  {
  //Code
  }

  template <>
  void Foo::function<int>(int&);
}
 
Hallo,

und schonmal danke für die Hilfe. Leider bekomme ich nun eine neue Fehlermeldung. :/

Code:
namespace XY{
  class Foo {
    template<typename T>
    void function(T& o); 
  };
}

Code:
template<typename T>
XY::Foo::functionT& o)
{
//Code
}

template<>
XY::Foo::function<int>(int&);

Fehler:
cpp:
Spezialisierung von »template<class T> void XY::Foo::function(int&)« in anderem Namensbereich

und
h:
aus Definition von »template<class T> void XY::Foo::function(T&)«
 
Zuletzt bearbeitet:
GCC 4.3.

Was soll an deinem Code anders sein, bis drauf das du den Namespcae direkt vorgibst?
 
Eben, dass die Sachen im Namespace stehen. ;) Ich müsste selber erstmal den Standard wühlen (und das ist bei Templates ziemlich ätzend), aber zum einen kann das Namelookup-Probleme verursachen und außerdem bin ich mir nicht sicher, ob die Syntax außerhalb des Namespaces überhaupt korrekt ist und falls ja, ob die explizite Instanziierung so funktionieren kann.

Der GCC 4.3 sollte das sonst eigentlich schlucken. Ich hab mal nen Trockenlauf (ohne Link halt) mit dem Comeau Online gemacht, der hat es einwandfrei gefressen.
 
Ok...ich denke da werde ich später nochmal einen Anlauf wagen :) Ich halte dich auf dem leufenden und danke herzlichst für den Rat :daumen:.
Ergänzung ()

Ok...kompilieren kann er. Schonmal sehr cool! Aber linken kann ich nich. Bekomme ne "undefined reference" nachricht. Dabei hab ich die Spezialisierung auch drin.
 
Zuletzt bearbeitet:
Wie lautet denn die exakte Fehlermeldung? Und welche expliziten Instanziierungen hast du denn eingefügt?
 
undefined reference
Ergänzung ()

Code sieht im Detail so aus:

Code:
namspace XY{
	template<typename T>
	T** interpolateImg(T upperLeft, T upperRight, T lowerRight, T lowerLeft, int size);
}

Code:
namespace XY{
	template<typename T>
	T** interpolateImg(T upperLeft, T upperRight, T lowerRight, T lowerLeft, int size)
	{
		T** array = new T*[size];
		for(int i=0; i<size; i++)
			array[i] = new T[size];

		for(unsigned int x=0; x < size; x++)
		{
			float tx = float(x)/float(size);
			float oneMinusTX = (float)1 - tx;
			for(unsigned int y=0; y < size; y++)
			{
				float ty = float(y)/float(size);
				float p1 = oneMinusTX*upperLeft + tx*upperRight;
				float p2 = oneMinusTX*lowerLeft + tx*lowerRight;
				T   p3 = T((1-ty)*p1 + ty*p2);
				array[x][y] = p3;
			}
		}

		return array;
	}

	template<>
	float** interpolateImg(float, float, float, float, int);
}
 
undefined reference auf was? Die Meldung muss doch wesentlich länger sein. Der interessante Teil fehlt leider.

Compiler-/Linkerauruf oder ggf. wenn machbar ein Minimalbeispiel würden auch helfen.
 
Zuletzt bearbeitet:
Legenbaer schrieb:
Code:
	template<>
	float** interpolateImg(float, float, float, float, int);
}
Code:
	template<>
	float** interpolateImg<float>(float, float, float, float, int);
}
in welcher zeile gibt er denn den fehler genau aus?
 
Ich kann die Bibliothek problemlos kompilieren. Der Fehler kommt wenn ich versuche gegen sie zu linken. Habe die beschriebene Funktion schon garnicht mehr als Template laufen....

Dafür frisst er meine neue Templateklasse auch nicht. Ich nutze CMake und das ding schreibt meine makefile. Und ich glaube es fängt auch einen Teil der Errors ab. Zumindest bekomme ich nur Fehler in der mit der Syntax:

Datei: Zeile: undefined reference to `Klasse<foo>::function(bar)'

Das bringt mich nicht weiter. Der code ist ok. Ich dreh langsam frei...
 
Hallo,

hast du die Fehlermeldung nachbearbeitet? Das foo und bar sieht nicht so aus, als wenn es da ursprünglich stand. Nur die exakte, vollständige Fehlermeldung (1:1 das was der Compiler/Linker auf die Konsole spuckt) ist hilfreich, da der interessante Teil wieder fehlt - es sei denn deine Klasse heißt Klasse und die Template-Argumente sind vom Typ foo und bar.

Hast du denn für deinen Typen foo das Template explizit instanziiert? Wird die Lib, in der sich die Instanziierung befinden, auch dazugelinkt?
 
Setzte für foo,bar und klasse ein was du möchtest. Das was da steht ist die Fehler syntax und mehr Infos bekomme ich nicht. Das er vernünftig linkt nehme ich mal an den wenn ich mal alle Objekte nicht über Templates realisiere gehts ja auch....

Wo kann ich denn anfangen nach Fehlern zu suchen?
 
Zuletzt bearbeitet:
was mir grad einfällt... du deklarierst die spezialisierung, definierst sie aber nicht. woher will der compiler nun wissen, was genau mit dieser spezialisierung geschehen soll? soll float nun auf int abgebildet werden oder auf char?

mal ein analoges beispiel dazu der modulo-operator, welcher ja nicht für double und float angewendet werden kann:
Code:
template <typename T> T mod( T x, T y )
{
  return x % y;
}

template <> double mod<double>( double x, double y )
{
  return x - static_cast<double>( static_cast<int>( x / y ) ) * y;
}
inwiefern dein code geändert werden muss, kann ich dir nicht sagen. das findest du schon selbst raus. ;)
 
So, sorry für die längere Auszeit.

Zum einen ist mir leider bei der Syntax für die explizite Instanziierung ein Fehler unterlaufen. Es müsste heißen:
Code:
namespace XY {
  [...]

  template void Foo::function<int>(int&);
}
oder auch

Code:
namespace XY {
  [...]

  template void Foo::function<>(int&);
}
falls, die Typen aus den Parametern ableitbar sind.

Allerdings sehe ich gerade, dass du für HistogrammRGB einen NonType-Templateparameter verwendest. Hast Du HistogrammRGB<10> explizit instanziiert?

@claW. : Es geht nicht um Spezialisierung, sondern um explizite Instanziierung. ;)
 
Zurück
Oben