Opened 7 years ago

Last modified 6 years ago

#11731 new Bugs

iostreams classes do not support C++11 move semantics

Reported by: Josh Chia <joshchia@…> Owned by: Jonathan Turkanis
Milestone: To Be Determined Component: iostreams
Version: Boost Development Trunk Severity: Problem
Keywords: Cc: ki.stfu@…

Description

At least some iostreams classes do not support C++11 move semantics. Attempts to "move-construct" them result in compiler errors. Such classes include but are probably not limited to filtering_istream.

#include <boost/iostreams/filtering_stream.hpp>

struct Foo {

Foo(Foo&& o)

: f(std::move(o.f)) { }

boost::iostreams::filtering_istream f;

};

Change History (2)

comment:1 by ki.stfu@…, 6 years ago

Hi!

I faced with the same problem when I tried to move boost::iostreams::stream<>. Here is my app:

#include <cassert>
#include <iostream>
#include <fstream>
#include <boost/iostreams/stream.hpp>

class MyDevice {
 public:
  typedef char char_type;
  typedef boost::iostreams::sink_tag category;

  explicit MyDevice(int i) { assert(i == 1); }

  std::streamsize write(const char_type* s, std::streamsize n)
  {
    std::cout << s << '\n';
    return n;
  }
};

boost::iostreams::stream<MyDevice> make_stream(int i) {
  return boost::iostreams::stream<MyDevice> (i); // ERROR
}

std::ofstream make_ofstream() {
 return std::ofstream ("test.txt", std::ofstream::out);
}

int main() {
  auto&& strm = make_stream(1); // ERROR
  strm << "12312313";

  boost::iostreams::stream<MyDevice> strm2(1); // OK
  strm2 << "12312313";

  make_ofstream() << " asdfasdf"; // OK for clang++-3.8 with -stdlib=libc++

  return 0;
}

I found couple classes that prevent compiler from implicitly-declaring move constructors. These classes have user-declared copy constructor/destructor and because of this reason we have to implement move operators by ourselves.

diff --git a/include/boost/iostreams/detail/buffer.hpp b/include/boost/iostreams/detail/buffer.hpp
index 72400f0..5174253 100644
--- a/include/boost/iostreams/detail/buffer.hpp
+++ b/include/boost/iostreams/detail/buffer.hpp
@@ -46,6 +46,7 @@ private:
 public:
     basic_buffer();
     basic_buffer(std::streamsize buffer_size);
+    basic_buffer(basic_buffer&&) { /* TODO implement move ctor and assign op */ }
     ~basic_buffer();
     void resize(std::streamsize buffer_size);
     Ch* begin() const { return buf_; }
diff --git a/include/boost/iostreams/detail/optional.hpp b/include/boost/iostreams/detail/optional.hpp
index 867dfbd..5067a97 100644
--- a/include/boost/iostreams/detail/optional.hpp
+++ b/include/boost/iostreams/detail/optional.hpp
@@ -49,6 +49,7 @@ public:
     typedef T element_type;
     optional() : initialized_(false) { }
     optional(const T& t) : initialized_(false) { reset(t); }
+    optional(optional&&) { /* TODO implement move ctor and assign op */ }
     ~optional() { reset(); }
     T& operator*()
     {
diff --git a/include/boost/iostreams/stream_buffer.hpp b/include/boost/iostreams/stream_buffer.hpp
index dbcb786..f9e54b7 100644
--- a/include/boost/iostreams/stream_buffer.hpp
+++ b/include/boost/iostreams/stream_buffer.hpp
@@ -84,6 +84,7 @@ public:
     BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
 public:
     stream_buffer() { }
+    stream_buffer(stream_buffer&& that) { /* TODO implement move ctor and assign op */ }
     ~stream_buffer()
     {
         try {

Can anyone look into this issue?

comment:2 by ki.stfu@…, 6 years ago

Cc: ki.stfu@… added
Version: Boost 1.57.0Boost Development Trunk
Note: See TracTickets for help on using tickets.