【问题标题】:ostringstream is empty after inserting output to itostringstream 插入输出后为空
【发布时间】:2018-05-26 09:53:48
【问题描述】:

我有一个奇怪的问题,即 ostringstream 为空,即使我向其中插入了输出。 这是我的代码:

//logger.h

#include <string>
#include <iostream>
#include <sstream>
using std::string;


class BasicLogger {
public:
    BasicLogger(const string name);
    BasicLogger(const BasicLogger& basicLogger);
    ~BasicLogger();

    template<class T>
    BasicLogger& operator<<(const T &msg){
        std::cout << "msg is: " << msg << std::endl;
        mBuf << msg;
        std::cout << "mBuf is: " << mBuf.str() << std::endl;
        return *this;
    }


private:
    string mName;
    std::ostringstream mBuf;
};


class Logger {
public:
    Logger();
    ~Logger();
    BasicLogger info();
    BasicLogger error();

private:
    BasicLogger mInfoLogger;
    BasicLogger mErrorLogger;

};

//logger.cpp

#include "logger.h"

BasicLogger::BasicLogger(const string name):
    mName(name) { }

BasicLogger::BasicLogger(const BasicLogger& otherLogger) {
    this->mName = otherLogger.mName;
    this->mBuf << otherLogger.mBuf.rdbuf();
}

BasicLogger::~BasicLogger() { }

Logger::Logger(): 
    mInfoLogger("[INFO]"),
    mErrorLogger("[ERROR]") {}

Logger::~Logger() {};

BasicLogger Logger::info() {
    return mInfoLogger;
}

BasicLogger Logger::error() {
    return mErrorLogger;
}

//main.cpp

#include "logger.h"

int main() {
    Logger logger;
    logger.info() << "Hellooo";
}

输出是

msg is: Hellooo
mBuf is: 

【问题讨论】:

  • info() 按值返回,因此您可以获得记录器的副本。
  • @BoPersson 你是对的!我没注意...谢谢!

标签: c++ stl ostringstream


【解决方案1】:

虽然@BoPersson 已经为您提供了解决方案,但我想解释一下这里发生了什么,以及为什么您的输出为空,即使您在显示其内容之前添加到ostringstream 行。

我认为当您尝试按值返回 mInfoLogger 时,编译器抱怨无法返回它,因为复制构造函数已被删除。它被删除的原因是因为您拥有的ostringstream 成员是不可复制的。

所以您提供了自定义复制构造函数并尝试以这种方式复制流:

this->mBuf << otherLogger.mBuf.rdbuf();

只有这不会复制任何内容,因为您的 rdbuf 是空的,而是设置 failbit

故障位

basic_ostream::operator的streambuf重载http://en.cppreference.com/w/cpp/io/ios_base/iostate

如果您要像这样检查您的消息插入:

if (!(mBuf << msg))
    std::cout << "Not Inserted" << std::endl;

您会看到 Not Inserted 消息打印。有很多方法可以让它打印出想要的信息。例如,确保您的rdbuf 缓冲区不为空,或者在重用mBuf 之前重置failbit,类似于mBuf.clear();,或者只是返回对mInfoLogger(和mErrorLogger)的引用。然后你就可以安全地摆脱你的复制构造函数了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 2014-08-10
    • 1970-01-01
    • 2011-06-03
    • 2019-03-15
    • 1970-01-01
    相关资源
    最近更新 更多