【问题标题】:Copy contructor error with no obvious copy没有明显副本的复制构造函数错误
【发布时间】:2013-04-21 13:39:16
【问题描述】:

我正在尝试从头开始构建一些简单的日志记录功能,使用类似“

#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 编译)之前将其敲掉。

我是否正确解释了这个问题,如果是,隐式副本在哪里,如何消除它?

【问题讨论】:

    标签: c++ iostream stringstream ostringstream


    【解决方案1】:

    第一个问题是std::ostringstream is non-copyable,您在创建Buffer 的副本时尝试创建它的副本。

    您在此return 语句中创建Buffer 副本的原因:

    return Buffer(*this);
    

    你的类Buffer 没有隐式生成的移动构造函数吗?而它之所以没有,是因为Buffer有一个用户自定义的析构函数,它抑制了move构造函数的隐式生成。

    你可以明确定义一个:

        Buffer(Buffer&& b)
            :
            mPar(b.mPar),
            os(std::move(b.os))
        {
        }
    

    但您应该意识到标准库的某些实现并不完全兼容,并且没有实现move constructor of std::ostringstream

    【讨论】:

    • 你为什么不std::moveb.mPar
    • @MemyselfandI: mPar 是一个左值引用。 std::move 返回一个右值引用。然后,您不能将右值引用分配给左值引用
    • 所以当你说 lvalue-reference 你的意思是 不是 一个 xvalue,只是一个常规变量?
    • @MemyselfandI:我不明白你的问题。 mPar 是一个左值引用。 std::move(b.mPar) 的结果是一个右值引用。你不能用右值引用初始化左值引用——如果你在做mPar(std::move(b.mPar)),你会这样做
    • 我在问int a = 5; 是否是左值引用。或者是这样的:int &amp;b = ab 的类型是左值引用,a 只是左值吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-10
    • 2013-12-30
    • 2023-04-01
    • 2014-10-11
    • 1970-01-01
    相关资源
    最近更新 更多