
Hi, I started using the iostreams library for a pet project. I thinks it's a great piece of software. However, I immediately stumbled in what I think it may be a defect. Consider this simple source device: #include <boost/iostreams/stream.hpp> struct Source : boost::noncopyable { typedef char char_type; typedef boost::iostreams::source_tag category; Source(int); // ctor std::streamsize read(char* s, std::streamsize n) { // implementation here } private: /* ... private members here */ }; int main() { boost::iostreams::stream<Source> s(0); } the boost::noncopyable up there has been put because the device keeps handles to OS resources whose duplication can be very expensive. I was amazed that the code above doesn't compile. This is the error message reported by VC7.1: C:\lib\Boost\include\boost-1_33\boost\iostreams\detail\wrap_unwrap.hpp(52) : error C2558: struct 'Source' : no copy constructor available or copy constructor is declared 'explicit' (full error message is very long and is reported, for reference, at the end of the message) It seems that a device must be copy-constructibile. In particular, the code above makes at least three short-lived copies of the device. Question is: why? I believe this requirement is unintended and not due to a conscious design choice, my arguments are: 1) it's not documented, there is no mention of such requirement in http://www.boost.org/libs/iostreams/doc/concepts/device.html 2) it's unnatural and I believe my case (where copying the device could be expensive) occurs more often in practice than the opposite case 3) from the error messages it seems that a copy is only required as a side-effect of the template machinery used in BOOST_IOSTREAMS_FORWARD. In fact, the offending line detail\wrap_unwrap.hpp(52) is: inline T wrap(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) { return t; } that requires T to be copy-constructible. Am I missing something? Thanks in advance, Ganesh ----- full error messaage follows C:\lib\Boost\include\boost-1_33\boost\iostreams\detail\wrap_unwrap.hpp(52) : error C2558: struct 'Source' : no copy constructor available or copy constructor is declared 'explicit' C:\lib\Boost\include\boost-1_33\boost\iostreams\stream_buffer.hpp(90) : see reference to function template instantiation 'T boost::iostreams::detail::wrap<T>(const T &,boost::disable_if_c<B,void>::type *)' being compiled with [ T=Source, B=false ] C:\lib\Boost\include\boost-1_33\boost\iostreams\stream_buffer.hpp(90) : while compiling class-template member function 'void boost::iostreams::stream_buffer<T,Tr,Alloc>::open(const T &,int,int)' with [ T=Source, Tr=std::char_traits<char>, Alloc=std::allocator<char> ] C:\lib\Boost\include\boost-1_33\boost\utility\base_from_member.hpp(69) : see reference to class template instantiation 'boost::iostreams::stream_buffer<T,Tr,Alloc>' being compiled with [ T=Source, Tr=std::char_traits<char>, Alloc=std::allocator<char> ] C:\lib\Boost\include\boost-1_33\boost\iostreams\stream.hpp(61) : see reference to class template instantiation 'boost::base_from_member<MemberType>' being compiled with [ MemberType=boost::iostreams::stream_buffer<Source,std::char_traits<char>,std::allocator<char>> ] C:\lib\Boost\include\boost-1_33\boost\iostreams\stream.hpp(98) : see reference to class template instantiation 'boost::iostreams::detail::stream_base<Device,Tr,Alloc>' being compiled with [ Device=Source, Tr=std::char_traits<char>, Alloc=std::allocator<char> ] TestVc2.cpp(26) : see reference to class template instantiation 'boost::iostreams::stream<Device>' being compiled with [ Device=Source ]