Re: [boost] library for type erasure

AMDG Alexander Nasonov, Instead of using anyT as the placeholder I think that creating separate placeholders for each argument may be better. It allows for better checking at compile time when the argument types really model different concepts. struct to_ostream; struct ostream : function_arg<to_ostream, 0> {}; struct ostreamable : function_arg<to_ostream, 1> {}; struct to_ostream : function<ostream&(ostream&, ostreamable&)> { template<class R, class Os, class T> R execute(Os& os, T& t) { return(os << t); } }; void f() { any<ostream> os(ref(cout)); any<ostreamable> value(1); to_ostream()(os, value); } In order to make this work the function pointers have to take arguments of a type that stores only enough information to convert it to the real type. Basically it would be boost::any with direct support for reference_wrappers added. This would also mean that the function pointers for a given operation are all identical regardless of the number of other functions. Thus, "up-casting" anys will work. The main disadvantage of this scheme appears when one or more arguments are not casted. This could happen with lambda expressions. The solution is to give the argument enough information to reconstruct the original type or a subset thereof. When the return type is an any the same method can be used to avoid making the return types different for different sets of operations and thereby disabling conversions. Additionally, the tables required can be used to implement "down-casts." In Christ, Steven Watanabe

Steven Watanabe wrote:
AMDG
Alexander Nasonov,
Instead of using anyT as the placeholder I think that creating separate placeholders for each argument may be better. It allows for better checking at compile time when the argument types really model different concepts.
struct to_ostream; struct ostream : function_arg<to_ostream, 0> {}; struct ostreamable : function_arg<to_ostream, 1> {}; struct to_ostream : function<ostream&(ostream&, ostreamable&)> { template<class R, class Os, class T> R execute(Os& os, T& t) { return(os << t); } }; void f() { any<ostream> os(ref(cout)); any<ostreamable> value(1); to_ostream()(os, value); }
So far I see only that it adds more complexity. 1) You introduced circular dependency between to_ostream operation and arguments 2) The any<> now takes argument wrappers rather than a list of operations If you need an operation that takes anys of different types why don't you do it in a straightforward manner? // Interface for storing reference_wrapper<ostream&> objects typedef any<ostream_ref_operations> ostream_ref; struct to_ostream : function<ostream_ref&(ostream_ref&, anyT const&)> { // ... };
... skiped ...
In Christ, Steven Watanabe
participants (2)
-
Alexander Nasonov
-
Steven Watanabe