Boost logo

Boost :

Subject: Re: [boost] RFC: type erasure
From: Steven Watanabe (watanabesj_at_[hidden])
Date: 2011-07-20 15:38:27


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*>.

>
> 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>.

>
> 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.
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);

In Christ,
Steven Watanabe




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