2011-03-27 6 views
12

Mi tercera pregunta aquí hoy ;-), pero soy muy nuevo en la programación de plantilla de C++ y la sobrecarga del operador.especialización de plantilla de C++ - definiciones múltiples de error de vinculador

Estoy tratando los siguientes:

terminallog.hh

//snipped code 

class Terminallog { 
public: 

    Terminallog(); 
    Terminallog(int); 
    virtual ~Terminallog(); 

    template <class T> 
    Terminallog & operator<<(const T &v); 
    template <class T> 
    Terminallog & operator<<(const std::vector<T> &v); 
    template <class T> 
    Terminallog & operator<<(const T v[]); 
    Terminallog & operator<<(const char v[]); 

//snipped code 
}; 

//snipped code 
template <class T> 
Terminallog &Terminallog::operator<<(const T &v) { 
    std::cout << std::endl; 
    this->indent(); 
    std::cout << v; 
    return *this; 
} 

template <class T> 
Terminallog &Terminallog::operator<<(const std::vector<T> &v) { 
    for (unsigned int i = 0; i < v.size(); i++) { 
     std::cout << std::endl; 
     this->indent(); 
     std::cout << "Element " << i << ": " << v.at(i); 
    } 
    return *this; 
} 

template <class T> 
Terminallog &Terminallog::operator<<(const T v[]) { 
    unsigned int elements = sizeof (v)/sizeof (v[0]); 
    for (unsigned int i = 0; i < elements; i++) { 
     std::cout << std::endl; 
     this->indent(); 
     std::cout << "Element " << i << ": " << v[i]; 
    } 
    return *this; 
} 

Terminallog &Terminallog::operator<<(const char v[]) { 
    std::cout << std::endl; 
    this->indent(); 
    std::cout << v; 
    return *this; 
} 
//snipped code 

intentar compilar el código, me da un error de vinculador:

g++ src/terminallog.cc inc/terminallog.hh testmain.cpp -o test -Wall -Werror 
/tmp/ccifyOpr.o: In function `Terminallog::operator<<(char const*)': 
testmain.cpp:(.text+0x0): multiple definition of `Terminallog::operator<<(char const*)' 
/tmp/cccnEZlA.o:terminallog.cc:(.text+0x0): first defined here 
collect2: ld returned 1 exit status 

Therfore Actualmente estoy golpeando mi cabeza contra la pared, buscando una solución. Pero no puedo encontrar uno en la pared ...

Sería muy bueno si alguien podría mostrar mi error

muchas gracias

ftiaronsem

Respuesta

13

Esta función

Terminallog &Terminallog::operator<<(const char v[]) { 
    std::cout << std::endl; 
    this->indent(); 
    std::cout << v; 
    return *this; 
} 

no es una plantilla, sino una función de miembro regular. Si este archivo .h está incluido en varios archivos .cpp, causará el error de definición múltiple que está viendo. Si lo declaras inline, el compilador permitirá las definiciones múltiples y tu error debería ser reparado.

inline 
Terminallog &Terminallog::operator<<(const char v[]) { 
+0

wow, perfectamente correcto. Muchas gracias. Pero todavía tengo una pregunta: tengo un protector de inclusión en ese archivo de encabezado. Por lo tanto, solo se debe incluir una vez. ¿Por qué estoy recibiendo este error sin embargo? – ftiaronsem

+0

@fitaronsem: incluya guardias que ayuden con definiciones múltiples _sólo_ dentro de una sola TU. Su error es un _link_ error, no un error de compilación; incluir guardias no ayuda cuando tiene múltiples definiciones en múltiples TU. Por lo tanto, como regla general, no coloque definiciones de función o variable no en línea o sin plantilla en un encabezado. –

+0

Incluya guardias para evitar que se incluya varias veces en el proceso de compilación de un archivo * single * .cpp, por lo tanto, evite el * error del compilador * de definir la clase varias veces. Sin embargo, el problema que está viendo no es un error del compilador, sino un * error del enlazador *. Es decir, cuando sus múltiples archivos .cpp se unen para crear el archivo ejecutable o la biblioteca final. Por lo tanto, debe decirle al vinculador que está bien aceptar copias múltiples * idénticas * de esta función, y 'en línea' cumple ese propósito. – Pablo

Cuestiones relacionadas