我正在尝试从头开始构建一些简单的日志记录功能,其中包含类似'<<'的流接口,我遇到了一些编译问题。以下是我的代码的基础知识:
#include <string.h>
#include <sstream>
#include <iostream>
class Logger
{
public:
class Buffer
{
public:
Buffer(Logger &parent) : mPar(parent)
{
}
~Buffer(void)
{
mPar.endline(os);
}
template<class T>
Buffer& operator<<(const T& x)
{
os << x;
return *this;
}
Logger& mPar;
std::ostringstream os;
};
Buffer write(void)
{
return Buffer(*this);
}
void endline(std::ostringstream& os)
{
std::cout << os.str() << std::endl;
}
};
int main(int argc, char **argv)
{
Logger log;
log.write() << "fred" << 3 << "bob";
}
我得到的错误是:
In file included from /usr/include/c++/4.6/ios:45:0,
from /usr/include/c++/4.6/istream:40,
from /usr/include/c++/4.6/sstream:39,
from test.cpp:2:
/usr/include/c++/4.6/bits/ios_base.h: In copy constructor ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’:
/usr/include/c++/4.6/bits/ios_base.h:788:5: error: ‘std::ios_base::ios_base(const std::ios_base&)’ is private
/usr/include/c++/4.6/bits/basic_ios.h:64:11: error: within this context
In file included from test.cpp:2:0:
/usr/include/c++/4.6/sstream: In copy constructor ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’:
/usr/include/c++/4.6/sstream:373:11: note: synthesized method ‘std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)’ first required here
/usr/include/c++/4.6/streambuf: In copy constructor ‘std::basic_stringbuf<char>::basic_stringbuf(const std::basic_stringbuf<char>&)’:
/usr/include/c++/4.6/streambuf:782:7: error: ‘std::basic_streambuf<_CharT, _Traits>::basic_streambuf(const __streambuf_type&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_streambuf<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>]’ is private
/usr/include/c++/4.6/sstream:60:11: error: within this context
/usr/include/c++/4.6/sstream: In copy constructor ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’:
/usr/include/c++/4.6/sstream:373:11: note: synthesized method ‘std::basic_stringbuf<char>::basic_stringbuf(const std::basic_stringbuf<char>&)’ first required here
test.cpp: In copy constructor ‘Logger::Buffer::Buffer(const Logger::Buffer&)’:
test.cpp:8:8: note: synthesized method ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’ first required here
test.cpp: In member function ‘Logger::Buffer Logger::write()’:
test.cpp:33:22: note: synthesized method ‘Logger::Buffer::Buffer(const Logger::Buffer&)’ first required here
从目前为止我能找到的,错误是因为你无法在ostringstream上调用复制构造函数。据我所知,我不是直接调用复制构造函数,而是我不复制Buffer,只在'return'语句中构造它。
另一件有趣的事情是,这个代码在Visual Studio 2010下编译得很好,在将它集成到我的应用程序(使用GCC 4.6.3编译)之前我将其删除。
我是否正确解释了问题,如果是这样的话 - 隐式副本在哪里,以及如何消除它?
答案 0 :(得分:6)
第一个问题是std::ostringstream
is non-copyable,您在创建Buffer
副本时尝试创建该副本。
您在此Buffer
声明中创建return
副本的原因:
return Buffer(*this);
您的班级Buffer
是否没有隐式生成的移动构造函数。它没有一个的原因是Buffer
有一个用户定义的析构函数,它禁止隐式生成移动构造函数。
您可以明确定义一个:
Buffer(Buffer&& b)
:
mPar(b.mPar),
os(std::move(b.os))
{
}
但是你应该意识到标准库的某些实现不完全符合,并且没有实现move constructor of std::ostringstream
。