
On 2012-06-24 18:34:13 +0000, Steven Watanabe said:
On 06/24/2012 08:13 AM, Dave Abrahams wrote:
Very interesting. Does either approach support operator overloading?
Yes. I put quite a bit of effort into making sure that operator overloads would work correctly.
I started the work on operator overloading, as you might guess when seeing the file include/poly/operators.hpp (names in this file will definitely change) I didn't get so far that poly::interface would actually recognize these callables and create the corresponding operators for itself, but that sure is possible. More importantly, I'm still kind of missing the point of why the feature of operator overloading is really needed. In essence: How should binary operators behave? Steven's TypeErasure defines binary operators such that only when the wrapped types of a and b are the same, can you sum them up: "a + b". But where would you use this kind of an "any", where only some of the instances can be added up, and others cause undefined behavior? Wouldn't you actually do the addition on the side where you know the types, and not on the type-erased side? Do we really have a real world use case that would prompt us to implement features like operator overloading? * * * Before releasing more worms from the can of type-erased operators, I must confess that I know still too little about the possible uses for type erasure / expression problem / what you name it. What I propose is we should look into how e.g. Haskell and Clojure programmers use their type classes and protocols. For one thing, I could only think of few examples where the interface would have mutating functions. (Anybody care to throw in more examples?) More typical use cases (that I could think of) are functions which read the wrapped type (as const reference), and then either (1) return a value, or (2) cause a side effect: std::string(to_html_, self const &); // (1) "pure" function void(print_, self const &, std::ostream &); // (2) side effect Maybe if the whole interface is about wrapping some sort of computation or side effect, it might make sense to have some non-const functions too: using progress = interface< std::size_t(total_progress_, self const &), std::size_t(current_progress_, self const &), void(run_for_, self &, std::chrono::microseconds)>; Or maybe it's modeling a kind of a container and you can insert items into it: using container = interface< void(insert_, self &, std::size_t, content), void(remove_, self &, std::size_t), content &(at_, self &, std::size_t), content const &(at_, self const &)>; -- Pyry Jahkola pyry.jahkola@iki.fi https://twitter.com/pyrtsa