2011-12-07 17 views
8

Possible Duplicate:
std::endl is of unknown type when overloading operator<<
Operator overloadingC++ concatenamento dell'operatore << per std :: cout come l'utilizzo

Attualmente sto programmando una classe logger, ma il metodo operator<< causa un errore di compilazione. Ecco una versione ridotta a icona della classe, nel file "logger.h":

#include <iostream> 
class Logger { 
public: 
    Logger() : m_file(std::cout) {} 

    template <typename T> 
    Logger &operator<<(const T &a) { 
     m_file<<a; 
     return *this; 
    } 

protected: 
    std::ostream& m_file; 
}; 

E 'incluso nel mio main.cpp e lavora in ottima posizione quando ho uscita una stringa letterale:

log << "hi"; 

Tuttavia, il seguente non verrà compilato.

#include "logger.h" 
int main() { 
    Logger log; 

    log << std::endl; 
} 

Le relazioni del compilatore g ++:

src/main.cpp:5: error: no match for 'operator<<' in 'log << std::endl'

risposta

11

Il tuo problema non riguarda la catena di <<, un singolo log << endl sarebbe anche causare il problema. È perché std::endl è una funzione template:

template <class charT, class traits> 
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os); 

Uno del sovraccarico di operator<< in basic_ostream è:

template <class charT, class traits = char_traits<charT> > 
class basic_ostream : virtual public basic_ios<charT,traits> { 
public: 
    basic_ostream<charT,traits>& operator<<(
    basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&)); 
//... 
}; 

Così i parametri del modello si può dedurre quando si utilizza std::cout<<std::endl. Tuttavia, quando il lato sinistro è il class Logger, la compilazione non può dedurre i parametri del modello di endl. Esplicitamente dare i parametri del modello possono lasciare programma di compilare e di lavoro:

#include <iostream> 
class Logger 
{ 
public: 
    std::ostream &m_file; 
    Logger(std::ostream &o = std::cout):m_file(o){}; 

    template <typename T> 
    Logger &operator<<(const T &a) { 
     m_file<<a; 
     return *this; 
    } 
}; 

int main() 
{ 
    Logger log; 
    log<<std::endl<char, std::char_traits<char> >; 
    log<<"hi"<<" stackoverflow"<<std::endl<char, std::char_traits<char> >; 
    return 0; 
} 

Oppure è possibile aggiungere un nuovo sovraccarico operator<< in class Logger di lasciare che il compilatore dedurre i parametri del modello di std::endl:

#include <iostream> 
class Logger 
{ 
public: 
    std::ostream &m_file; 
    Logger(std::ostream &o = std::cout):m_file(o){}; 

    template <typename T> 
    Logger &operator<<(const T &a) { 
     m_file<<a; 
     return *this; 
    } 

    Logger &operator<<(std::ostream& (*pf) (std::ostream&)){ 
     m_file<<pf; 
     return *this; 
    } 
}; 

int main() 
{ 
    Logger log; 
    log<<std::endl; 
    log<<"hi"<<" stackoverflow"<<std::endl; 
    return 0; 
} 

Inoltre, se non hai bisogno che l'output venga svuotato immediatamente, puoi usare '\ n' invece di endl.

+2

"Inoltre, è possibile utilizzare '\ n' invece di' endl'." No, se l'OP vuole assicurarsi che i buffer di uscita siano scaricati, come ho appreso recentemente (http://stackoverflow.com/q/8311058/440558). –

+0

Bene, lo aggiungerò alla mia risposta. – fefe

+0

Grazie, funziona :) – Tuxer

0

L'errore è causato da std::endl che è una funzione. Fare riferimento a:

std::endl is of unknown type when overloading operator<<

+0

'std :: cout' è una funzione? – jalf

+3

Penso che Eric volesse dire che 'std :: endl' è una funzione. –

+0

Immagino tu voglia dire "' std :: endl' è un modello di funzione "? –

Problemi correlati