2013-02-19 65 views
4

我想創建一個類,它可以幫助我通過使用3D呈現器提供std :: cout或QDebug類似功能來進行調試。重載操作符<<用於文本呈現

我有以下渲染方法,我現在使用

IRenderer::renderText(int posX, int posY, const float* color, const char* text, ...); 

// E.g. 
int i; 
float f; 
float color[] = {1, 1, 1, 1}; 

renderer->renderText(50, 50, color, "Float %f followed by int %i", f, i); 

其實,這工作得很好,但我不知道是否有可能創建一個類,它可以讓我做這樣其中:

debug() << "My variables: " << i << ", " << "f"; 

我假設會有一個模板函數,它會根據輸入類型構建傳遞到renderText()的字符串,但我不太清楚如何實現它。

回答

2

羅布的回答另一種方法是在您的自定義logger類的ostringstream,並使用析構函數做記錄:

#include <iostream> 
#include <sstream> 

class MyLogger 
{ 
protected: 
    std::ostringstream ss; 

public: 
    ~MyLogger() 
    { 
     std::cout << "Hey ma, I'm a custom logger! " << ss.str(); 

     //renderer->renderText(50, 50, color, ss.str()); 
    } 

    std::ostringstream& Get() 
    { 
     return ss; 
    } 
}; 

int main() 
{ 
    int foo = 12; 
    bool bar = false; 
    std::string baz = "hello world"; 

    MyLogger().Get() << foo << bar << baz << std::endl; 

    // less verbose to use a macro: 
#define MY_LOG() MyLogger().Get() 
    MY_LOG() << baz << bar << foo << std::endl; 

    return 0; 
} 
+0

而不是使用宏,我建議你爲MyLogger類定義'template MyLogger&operator <<(T const&)',這與'ss' – kassak 2013-02-19 12:02:34

0

我喜歡從std :: ostream派生我的日誌類,所以我得到了所有的流善良。訣竅是將所有特定於應用程序的代碼放入關聯的streambuf類中。考慮這個工作示例。要修改它酬勞您的需求,簡單地重寫CLogBuf::sync(),就像這樣:

int sync() { 
    renderer->renderText(50, 50, color, "%s", str()); 
    str(""); 
    return false; 
} 

例子:

#include <iostream> 
#include <sstream> 

class CLogger : public std::ostream { 
private: 
    class CLogBuf : public std::stringbuf { 
    private: 
     // or whatever you need for your application 
     std::string m_marker; 
    public: 
     CLogBuf(const std::string& marker) : m_marker(marker) { } 
     ~CLogBuf() { pubsync(); } 
     int sync() { std::cout << m_marker << ": " << str(); str(""); return !std::cout; } 
    }; 

public: 
    // Other constructors could specify filename, etc 
    // just remember to pass whatever you need to CLogBuf 
    CLogger(const std::string& marker) : std::ostream(new CLogBuf(marker)) {} 
    ~CLogger() { delete rdbuf(); } 
}; 

int main() 
{ 
    CLogger hi("hello"); 
    CLogger bye("goodbye"); 

    hi << "hello, world" << std::endl; 
    hi << "Oops, forgot to flush.\n"; 
    bye << "goodbye, cruel world\n" << std::flush; 
    bye << "Cough, cough.\n"; 
} 
+0

你甚至都不需要創建臨時的記錄:'CLogger( 「你好」)<< 「你好,世界」 <<的std :: ENDL;' – congusbongus 2013-02-19 03:57:43

+0

@CongX你是的,你確實需要命名的對象。臨時程序不能綁定到非常量引用,如'operator >>(ostream&,const char *)'。請參閱http://stackoverflow.com/questions/14381311/ostrstream-interprets-constant-string-as-pointer – 2013-02-19 04:03:06

+0

任何方式來做到這一點,而不使用流? – jaho 2013-02-25 19:19:12