|
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