Linkproblem: Mehrfach definierte Template-Spezialisierung



  • Hi!

    Ich hab eine Template-Spezialisierung in einem Header-File. dieses File wird von 2 Dateien inkludiert (A.cpp und B.cpp). Diese beiden Files moechte ich nun zusammenlinken. Das geht nicht ("multiple declaration of .....").

    Das Problem: die beiden Files moecht ich auch unabhaengig voneinander linken koennen. Sprich A.cpp kommt in Binary A, B.cpp kommt in Binary B... A.cpp und B.cpp kommen gemeinsam in Binary AB.

    Gibts fuer solche Faelle eine idiomatische Loesung?


  • Mod

    ...



  • SeppJ schrieb:

    ...

    Sitz ich auf der Leitung und das Problem liegt ganz woanders, oder gibts eine offensichtliche Loesung die mir grad nicht einfaellt?



  • Ich dachte, Templates wären immer static (und vielleicht auch inline). Kannst du mal bitte ein Minimalbeispiel posten?
    Zudem sieht mir multiple declaration eher nach Compiler- und nicht Linkerfehler aus.


  • Mod

    Blue-Tiger schrieb:

    Gibts fuer solche Faelle eine idiomatische Loesung?

    inline.



  • Blue-Tiger schrieb:

    Gibts fuer solche Faelle eine idiomatische Loesung?

    extern.


  • Mod

    Oppositant schrieb:

    Blue-Tiger schrieb:

    Gibts fuer solche Faelle eine idiomatische Loesung?

    extern.

    Beispiel?



  • Minimalbeispiel:

    header.h:

    #ifndef FOO_H
    #define FOO_H
    
    template<typename T>
    class Foo
    {
    	public:
    		bool something();
    };
    
    template<>
    bool Foo<int>::something() {
    	return false;
    }
    
    template<typename T>
    bool Foo<T>::something() {
    	return false;
    }
    
    #endif
    

    a.cpp:

    #include "header.h"
    #include <iostream>
    using namespace std;
    
    void main_a()
    {
    	Foo<int> f;
    	cout << f.something() << endl;
    }
    

    b.cpp:

    #include "header.h"
    #include <iostream>
    using namespace std;
    
    void main_b()
    {
    	Foo<int> f;
    	cout << f.something() << endl;
    }
    
    tom@blulap:workspace$ g++ -c a.cpp -o a.o
    tom@blulap:workspace$ g++ -c b.cpp -o b.o
    tom@blulap:workspace$ g++ a.o b.o -o test
    b.o: In function `Foo<int>::something()':
    b.cpp:(.text+0x0): multiple definition of `Foo<int>::something()'
    a.o:a.cpp:(.text+0x0): first defined here
    /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o: In function `_start':
    (.text+0x20): undefined reference to `main'
    collect2: ld returned 1 exit status
    


  • Ich habe das so wie du noch nie gemacht, aber ginge es eventuell so:

    #ifndef FOO_H
    #define FOO_H
    
    template<typename T>
    class Foo
    {
        public:
            bool something()
            {
                return false;
            }
    };
    
    template<typename T>
    class Foo<int>
    {
        public:
            bool something()
            {
                return false;
            }
    };
    
    #endif
    


  • Camper hatte recht, "inline" hilft 🙂


  • Mod

    Die Spezialisierung eines Funktionstemplates ist eine Funktion. Die üblichen ODR-Regeln für Funktionen sind folglich anzuwenden.


Anmelden zum Antworten