Variadic Template class + Auslagerung von Deklaration/Implementierung



  • Guten Abend,

    wie der Name schon sagt arbeite ich an einer Klasse welche beliebig viele Template Parameter verarbeiten kann. Dabei bin ich allerdings über Probleme gestolpert, sodass ich mir das entsprechende Kapitel aus dem Buch Templates angeschaut habe. Mir ist aufgefallen dass die Klassenmember direkt definiert werden ohne sie aufzuteilen in Deklaration für die Headerdatei und Implementierung für die cpp-Datei. Deswegen habe ich auch die Beispielklasse aus dem Buch genommen und versucht die eigenmächtig zu separieren. Das kam dabei raus.

    Header:

    #ifndef TUPLE_H
    #define TUPLE_H
    
    template<typename... T> class Tuple;
    
    template<typename H, typename... T> class Tuple<H, T...>
    {
    private:
    	H head;
    	Tuple<T...> tail;
    
    public:
    	Tuple();
    
    	Tuple(const H& head, const Tuple<T...>& tail);
    };
    
    template <> class Tuple<> { };
    
    #endif
    

    Implementierung:

    #include "tuple.h"
    
    template<typename H, typename... T> Tuple<H, T...>::Tuple()
    {
    }
    
    template<typename H, typename... T> Tuple<H, T...>::Tuple(const H& head, const Tuple<T...>& tail) : head{ head }, tail{ tail }
    {
    }
    

    Das alleine zu erstellen ging fehlerfrei, aber sobald ich versuche in der main Funktion gebrauch davon zu machen

    #include <iostream>
    #include <string>
    
    #include "tuple.h"
    
    int main(int argc, char** argv)
    {
    	Tuple<int, double, std::string> tuple;
    	return 0;
    }
    

    passiert folgendes:
    1>program.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: __thiscall Tuple<int,double,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >::Tuple<int,double,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >(void)" (??0?Tuple@HNV?Tuple@HNV?basic_string@DU?chartraits@D@std@@V?char_traits@D@std@@V?allocator@D@2@@std@@@@QAE@XZ)" in Funktion "_main".
    1>C:\Users\Jan\source\repos\TestExec\Debug\TestExec.exe : fatal error LNK1120: 1 nicht aufgelöste Externe

    Ich habe nach dem Fehler gegooglet und ich weiß was das bedeutet hatte den schon oft an anderen nicht so komplizierten Stellen glücklicherweise.

    Vielleicht kann mir da jemand helfen?

    Mit freundlichen Grüßen,

    Jan



  • Bei Templates generiert der Kompiler die Definition für eine bestimmte Instanziierung (schreibt man das so?). Damit der Kompiler das machen kann, muss die vollständige Templatedefinition in Header-Dateien vorliegen. Wenn Du in main.cpp die Tuple verwendest, möchte er main.cpp kompilieren mit der speziellen Instanziierung Deiner Template.

    Allerdings geht das nicht, wenn nicht alle Defintionen schon in Tuple.h vorliegen. Hoffe das macht so Sinn. Eine Tuple.cpp macht keinen Sinn - welche Version von Tuple sollte der Kompiler denn kompilieren? Theoretisch gibt es doch unendlich viele verschiedenen Arten von Tuple.

    Das kann jemand anders bestimmt schöner erklären, aber in etwa so stelle ich mir das in meinem chaotischen Hirn vor 😅

    Auf gut Deutsch: Die Konstruktoren müssen ebenfalls in Tuple.h bleiben.


Log in to reply