Boost logo

Boost :

Subject: Re: [boost] RFC: type erasure
From: Fernando Pelliccioni (fpelliccioni_at_[hidden])
Date: 2011-07-20 15:53:05


Hi,

On Wed, Jul 20, 2011 at 4:38 PM, Steven Watanabe <watanabesj_at_[hidden]>wrote:

> AMDG
>
> On 07/20/2011 12:11 PM, Fernando Pelliccioni wrote:
> >
> > Hi Steven,
> >
> > I want to write something like this ...
> >
> >
> > void test_iostream_concept()
> > {
> > typedef mpl::vector<
> > ostreamable<>,
> > destructible<>
> > > requirements;
> >
> > typedef any< requirements, _self&> any_type;
> >
> >
> > typedef std::vector<any_type> ostr_vec;
> > ostr_vec vec;
> >
> > //boost iostreams
> > io::stream<writer_1> writer1;
> > io::stream<writer_2> writer2;
> > io::stream<io::file_sink> file_writer;
> > io::stream<io::null_sink> null_writer;
> >
> > std::ofstream f1("test.txt");
> >
> > vec.push_back( any_type(writer1) );
> > vec.push_back( any_type(std::cout) );
> > vec.push_back( any_type(f1) );
> >
> > ostr_vec::const_iterator it = vec.begin();
> > ostr_vec::const_iterator end = vec.end();
> >
> > for ( ; it != end; ++it )
> > {
> > std::cout << *it << std::endl;
> > //(*it) << "hello " << "world!"; //(1) compile-time error.
> > any_type do not support operator<<
> > }
> >
> > }
> >
>
> In this case, you don't need type erasure.
> io::stream is a std::ostream. You'd be better
> off using std::vector<std::ostream*>.
>

Sure, it is true, but, the example isn't complete, I need to add another
Custom Concept, *left_shift + lockable (mutex).*

>
> >
> > The line (1) do not compile because *any_type* do not has *operator<<.*
> >
> >
> > I could create my *custom concept*, like this...
> >
> > template<class C, class T>
> > struct bitwise_left_shift : primitive_concept<bitwise_left_shift<C, T>,
> > void(C&, const T&)>
> > {
> > static void apply( C& ostr, const T& arg )
> > {
> > ostr.operator<<(arg);
> > //ostr << arg;
> > }
> > };
> >
> > I used in this way ... it works!!!
> >
> > void test_custom_concept_bitwise_left_shift()
> > {
> > any<bitwise_left_shift<_self, *int*>, _self&> ostr( std::cout );
> >
> > int i = 10;
> > bitwise_left_shift<_self, int>()(ostr, i);
> >
> > }
> >
>
> This is basically what ostreamable does. You can
> use ostreamable<_self, int>.
>

Perfect!

>
> >
> > BUT!.... *ostr* object only works for *int's.*
> > *
> > *
> > How do I get *ostr* works generically?
> > *
> > *
> >
> > Something like this...
> >
> > void test_custom_concept_bitwise_left_shift()
> > {
> > //pseudo-code, do not compiles
> >
> > any<bitwise_left_shift<_self, *T*>, _self&> ostr( std::cout );
> >
> > int i = 10;
> > bitwise_left_shift<_self, *T*>()(ostr, i);
> >
> > float ff = 10.98;
> > bitwise_left_shift<_self, *T*>()(ostr, ff);
> >
> > }
> >
> >
> > How I define *T* ?
> >
>
> Unfortunately, it's impossible to allow streaming
> arbitrary types like this. The dispatching required
> conflicts fundamentally with separate compilation.
>

Ups!

> There are a few ways to approximate it, though.
>
> a) Use std::ostream. I would strongly encourage
> you to take this route if it is possible.
>
b) Enumerate all the possible stream types, and
> use boost::variant<std::ostream*, ...>.
> c) Enumarate all the types that you need to work with:
>
> typedef mpl::vector<
> ostreamable<_self, int>,
> ostreamable<_self, float>,
> ...
> > concept;
>
> any<concept, _self&> ostr(std::cout);
>
>
mmmm, I have to do in a type unsafe way...

Thanks a lot!
Fernando.


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