Why can't an object containing a ostringstream member be constructed?

半腔热情 提交于 2019-12-01 06:25:44

问题


I have the following class example, simplified from a larger project. It's based on a logging framework that uses the logger's scope to terminate a log entry in the destructor.

The code below will not compile because the constructor is an implicitly deleted function (edit: not true), which seems to have something to do with the std::ostringstream object. I'm confused about that because I think I should be able to directly construct a std::ostringstream, which would mean I should be able to directly construct a Container object.

#include <iostream>
#include <sstream>

class Container {
  public:
    std::ostringstream  bufferStream;

  public:
    Container();    // constructor
    ~Container();
};

Container::Container() {
    bufferStream << "Hello ";
}

Container::~Container() {
    std::cout << bufferStream.str() << " [end]" << std::endl;
}

// === Main method ===

int main() {

    Container().bufferStream << "world";   // works fine

    {                                      // causes tons of compiler errors
        Container cont = Container();
        cont.bufferStream << "world!";
    }

    return 0;
}

Note that the line labeled "works fine" does just that. It seems to instantiate an anonymous Container object, which contains a new std::ostringstream, which can be directly accessed to output "world". The Container itself creates the "Hello" part of the message and its destructor flushes the buffer.

Why doesn't the second part, in which the Container object is named and saved, run correctly? Here is a sample of the errors I get:

error.cpp: In function ‘int main()’:
error.cpp:28:36: error: use of deleted function ‘Container::Container(const Container&)’
         Container cont = Container();
                                    ^
error.cpp:4:7: note: ‘Container::Container(const Container&)’ is implicitly deleted because the default definition would be ill-formed:
 class Container {
       ^
error.cpp:4:7: error: use of deleted function ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’
In file included from error.cpp:2:0:
/usr/include/c++/4.8/sstream:387:11: note: ‘std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&)’ is implicitly deleted because the default definition would be ill-formed:
     class basic_ostringstream : public basic_ostream<_CharT, _Traits>

... and so on.


回答1:


This would work fine:

Container cont;
cont.bufferStream << "world!";

But this:

Container cont = Container();

involves the copy constructor. std::ostringstream is not copy-constructible which makes Container not copy-constructible, hence the error message talking about how Container::Container(const Container&) is implicitly deleted due to std::basic_ostringstream<char>::basic_ostringstream(const std::basic_ostringstream<char>&) being implicitly deleted.

Note that even though this copy would be elided, a requirement of copy/move elision is that the copy/move must be possible to begin with.




回答2:


As Barry explained, the ostringstream isn't copy constructible. As the default copy constructor copy-constructs member by member, it can't be generated here.

However, if you'd follow the rule of three you'd create a copy constructor (and also a copy assignment operator), doing what is needed for the stringstream. Then it would work:

class Container {
    ...
    Container(const Container&); //Copy constructor
};  

Container::Container(const Container &c) {
    bufferStream << c.bufferStream.rdbuf(); 
}

Online demo



来源:https://stackoverflow.com/questions/36409259/why-cant-an-object-containing-a-ostringstream-member-be-constructed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!