Boost logo

Boost :

From: Alberto Ganesh Barbati (abarbati_at_[hidden])
Date: 2005-10-25 03:27:53


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
        ]


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk