2010-11-04 6 views
0

Je rencontre une erreur de liaison étrange. J'ai suivi les instructions présentées here pour éviter ce genre de problèmes, mais je n'arrive pas à comprendre comment diviser les en-têtes et les fichiers d'implémentation.Erreur de liaison: surcharge de l'opérateur ami modèle

Voici mon fichier de test:

#include <cargo.h> 
#include <iostream> 
#include <string> 

using namespace std; 
using namespace dom; 

int main() 
{ 
    dom::cargo<string> text("Hello, World!"); 

    cout << text << endl; 

    return 0; 
} 

fichier d'en-tête class cargo inclus dans le test:

#ifndef CARGO_H 
#define CARGO_H 1 

#include "node.h" 

#include <iostream> 

namespace dom 
{ 
    template <typename Type> class cargo; 

    template <typename Type> 
    std::ostream& operator<<(std::ostream&, const dom::cargo<Type>&); 

    template <typename Type> 
    class cargo 
     : public dom::node 
    { 
     Type value; 

    public: 
     cargo() 
      : value() 
     { } 

     cargo(Type value) 
      : value(value) 
     { } 

     friend std::ostream& operator<< <>(std::ostream&, const dom::cargo<Type>&); 
    }; 
} 

#endif // !CARGO_H 

Et sa mise en œuvre:

#include "cargo.h" 

template <typename Type> 
std::ostream& operator<< (std::ostream& ostream, dom::cargo<Type>& cargo) 
{ 
    return (ostream << cargo.value); 
} 

J'utilise CMake pour compiler et reliez tout cela à togather. L'erreur lien que je reçois est sur la référence non définie à operator <<:

Scanning dependencies of target test 
[100%] Building CXX object Tests/CMakeFiles/test.dir/test0.c++.o 
Linking CXX executable test 
CMakeFiles/test.dir/test0.c++.o: In function `main': 
test0.c++:(.text+0x9b): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& dom::operator<< <std::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::basic_ostream<char, std::char_traits<char> >&, dom::cargo<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&)' 
collect2: ld returned 1 exit status 
make[2]: *** [Tests/test] Error 1 
make[1]: *** [Tests/CMakeFiles/test.dir/all] Error 2 
make: *** [all] Error 2 

Qu'est-ce que je fais mal? Aidez-moi, s'il vous plaît!

Répondre

2

Les modèles de fonction (membre) ne sont pas des fonctions; l'éditeur de liens ne les voit pas à moins que vous ne les instanciez. Les fichiers source sont compilés séparément, donc si vous mettez un modèle de fonction (membre) dans un fichier source et que vous ne l'instanciez pas explicitement, l'éditeur de liens ne le voit pas. Par conséquent, dans votre cas, le modèle de fonction n'a pas été transformé en fonction dans cargo.o, de sorte que l'éditeur de liens signale une erreur car main.o en dépend. Vous devez placer le modèle dans le fichier d'en-tête ou l'instancier explicitement dans cargo.cpp.

+0

Compris! Je vous remercie! :) – Rizo