Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 484
Ethan T Avatar asked Dec 10 '22 17:12

Ethan T


1 Answers

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.

like image 166
Barry Avatar answered Mar 09 '23 00:03

Barry