2011-12-07 36 views
8

Possible Duplicate:
std::endl is of unknown type when overloading operator<<
Operator overloadingC++ chaining của toán tử << cho std :: cout như sử dụng

Tôi hiện đang lập trình một lớp logger, nhưng phương pháp operator<< gây ra một lỗi biên dịch. Dưới đây là một phiên bản thu nhỏ của lớp, trong tập tin "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; 
}; 

Nó được bao gồm trong main.cpp tôi và các công trình perfecly khi tôi ra một chuỗi chữ:

log << "hi"; 

Tuy nhiên, sau đây sẽ không biên dịch.

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

    log << std::endl; 
} 

Các g ++ báo cáo trình biên dịch:

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

Trả lời

11

Vấn đề của bạn không phải là về chuỗi <<, một đơn log << endl cũng sẽ gây ra vấn đề. Đó là vì std::endl là một mẫu chức năng:

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

Một trong những tình trạng quá tải của operator<< trong basic_ostream là:

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>&)); 
//... 
}; 

Vì vậy, các thông số mẫu có thể được suy luận khi std::cout<<std::endl được sử dụng. Tuy nhiên, khi bên trái là class Logger, biên dịch không thể suy ra các tham số mẫu của endl. Một cách rõ ràng cho các thông số mẫu có thể để chương trình biên dịch và làm việc:

#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; 
} 

Hoặc bạn có thể thêm một tình trạng quá tải mới của operator<< trong class Logger để cho trình biên dịch suy ra các thông số mẫu của 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; 
} 

Ngoài ra, nếu bạn không cần đầu ra bị xóa ngay lập tức, bạn có thể sử dụng '\ n' thay vì endl.

+2

"Ngoài ra, bạn có thể sử dụng '\ n' thay vì' endl'. " Không phải nếu OP muốn đảm bảo các bộ đệm đầu ra được xóa, như tôi [đã học gần đây] (http://stackoverflow.com/q/8311058/440558). –

+0

Phải, tôi sẽ thêm nó vào câu trả lời của tôi. – fefe

+0

Cảm ơn bạn, nó hoạt động :) – Tuxer

0

Lỗi được gây ra bởi std::endl là một hàm. Tham khảo:

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

+0

'std :: cout' là một hàm? – jalf

+3

Tôi nghĩ Eric muốn nói rằng 'std :: endl' là một hàm. –

+0

Tôi đoán bạn có nghĩa là "' std :: endl' là một mẫu chức năng "? –

Các vấn đề liên quan