c++ - 两阶段查找运算符 << 问题?

标签 c++ c++11 g++

我正在尝试将我自己的代码从 VS2012 移植到 g++4.8。

我遇到了这个编译错误:

AllocationManager.cpp: In member function ‘void AllocationManager::printMemoryLeaks()’:
TRLogger.h:247:42: error: ‘streamAggrator’ was not declared in this scope
 #define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "
                                          ^
AllocationManager.cpp:39:2: note: in expansion of macro ‘TRLOG_INFO’
  TRLOG_INFO << "sdfs\n"; 

其中 printMemoryLeaks 是一个虚拟函数(AllocationManager 未模板化):

void AllocationManager::printMemoryLeaks(void)
 {

    TRLOG_INFO << "sdfs\n"; 
}

在文件 TRLogger.h 中:

enum TLogLevel {logERROR, logWARNING, logINFO, logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4};

class streamAggrator
{
public:
    streamAggrator(TLogLevel logLevel);

/* private: */ 
    FILELog fLog;
    WarnLog wlog;
    std::ostringstream& s1; 
    std::ostringstream& s2; 
};


template<typename T>
streamAggrator& operator<<(streamAggrator& agg, const T& obj) 
{
    agg.s1 << obj;
    agg.s2 << obj;
    agg.s2.flush();
    return agg; 
}

....

#define TRLOG_INFO streamAggrator(logINFO) << PACKET_DESCRIPTION << __FUNCTION__ << ":" << __LINE__ << ": "

我该如何解决这个函数 - 我没有找到任何可以使用 thisusing 来帮助编译器的地方。

谢谢, 盖伊

最佳答案

您的直接问题是您尝试将临时 streamAggrator 对象传递给一个函数,该函数通过非 const 引用采用 streamAggrator。您不能将临时对象绑定(bind)到非 const 引用。解决此问题的方法是使输出运算符成为 streamAggrator 的成员:虽然您不能将临时值绑定(bind)到非 const 引用,但您可以 调用非 const 成员函数。请注意,您还会遇到诸如 std::flush 之类的操纵器的问题(问题在于这些本身就是模板,您实际上需要一个具体的运算符来调用它们以使编译器推断出它们模板参数)。

显然,我会正确地解决这个问题,即,我不会尝试挖掘不创建流的解决方案,而是创建一个 std::streambuf do do实际工作。你的例子没有做任何有用的事情,也就是说,我真的不知道你在做什么,但代码看起来非常像尝试做类似 teestream 的事情:写一次但将输出发送到多个目的地。我在帖子中多次发布了相应的流缓冲区(虽然主要是在 Usenet 上,但我认为至少在 Stackoverflow 上也有一次)。

虽然我不知道如何摆脱宏来填充__FILE____LINE__,但实际的流格式可能应该使用流缓冲区:

struct teebuf: std::streambuf {
private:
    std::streambuf* sb1;
    std::streambuf* sb2;
public:
    teebuf(std::streambuf* sb1, std::streambuf* sb2): sb1(sb1), sb2(sb2) {}
    int overflow(int c) {
        this->sb1->sputc(c);
        this->sb2->sputc(c);
        return std::char_traits<char>::not_eof(c);
    }
    int sync() {
        this->sb1->pubsync();
        this->sb2->pubsync();
    }
};
class logstream
    : std::ostream {
    std::ofstream out;
    teebuf        sbuf;
public:
    logstream()
        : out("file.log")
        , sbuf(out.rdbuf(), std::clog.rdbuf()) {
        this->init(&this->sbuf);
    }
    logstream(logstream&& other)
        : out(std::move(other.out))
        , sbuf(std::move(other.sbuf)) {
        this->init(&this->sbuf);
};

认为您可以返回日志流。我不知道您的日志记录级别是用来做什么的,但我猜它的处理在准备问题时被删除了:可能需要更改实现以适本地考虑日志记录级别。

关于c++ - 两阶段查找运算符 << 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20589193/

相关文章:

C++ - 你能将一个静态库构建到另一个静态库中吗?

c++ - 如何为 std::unordered_set 定义自定义键等价谓词?

c++ - C++11中根据类型要求特化类模板成员函数

c++ - 如何使用 UNUSED 宏来消除 CONSTEXPR 函数中的警告?

c++ - 基于泰勒级数的基于模板的 Sin() 实现产生不正确的结果 C++

c++ - 如何将 herader 从二进制数据中分离出来

c++ - C++中的双重排序

c++ - 将应用程序链接到 libbz2.so.1 而不是 libbz2.so.1.0

gcc - 由于 gcc 编译器版本不受支持,Caffe 编译失败

c++ - 注意 : 'std::thread' is defined in header '<thread>' ; did you forget to '#include <thread>' ?