
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