
On Feb 20, 2009, at 9:08 PM, Vladimir Batov wrote:
It seems like there's still a lot of discussion going on about the interface even when Vladimir is plodding on, so I thought I might offer another candidate that I haven't seen put forth just yet.
I personally do not mind wotking in such a mode. I am merely implemeting what we are seemingly settling on (as far as my interpretation goes) like 'convert' as a class, etc. to see how it works out in reality. And, therefore, my "plodding on" should not be an ideas' deterrent of any kind.
Thanks, just wanted to make sure I was being polite :)
template<class Target, class Source> *unspecified-type* convert_to(const Source& value);
This would give us the flexibility to easily implement an interface that could be used like so:
int i = convert_to<int>("5").get(); // get "5" converted to int (throw on error)
unsigned u = convert_to<unsigned>("-1").get_or(0); // get "-1" converted to unsigned or else 0
int i = convert_to<int>("0xff").get_special(as_hex()); // get "0xff" converted to int using as_hex functor
My immediate concern is a lot of new vocabulary introduced. That can provide tons of useful stuff... that the majority of people might never use.
I had this concern too, though as_hex was just an example of something a user might write if they wanted some special kind of conversion, not something to include in the library.
Secondly, I am not sure what are the advantages of the alternative interface above. We seem to achieve all the above with the existing interface and only 1 (!) new keyword ("convert_to") in stad of 5 (convert_to, get, get_or, get_special, as_hex).
Fair enough. The goals of the interface were: 1. Be able to provide a default value w/o type deducing being a problem. (ie: making the interface unclear) 2. Have the same interface when used as a functor. 3. Be very explicit and clear about if you're getting throwing behavior or defaulting behavior.
// get "5" converted to int (throw on error) int i = convert_to<int>("5")(throw_t());
So could I do the following? vector<string> s; vector<int> i; transform (s.begin(), s.end(), back_inserter(i), convert_to<int, string>(throw_t()));
// get "-1" converted to unsigned or else 0 unsigned u = convert_to<unsigned>("-1", 0);
In this case <unsigned> isn't necessary, type deducing kicks in and we could just as well write: unsigned u = convert_to("-1", 0); Which reads to me as "convert to -1 from 0". And if we change "convert_to" to "convert" it becomes even more confusing.
// get "0xff" converted to int using as_hex functor int i = convert_to<int>("0xff") >> std::hex;
I thought operator>>() returns an istream? If there's precedent somewhere where it doesn't return an istream, forgive my ignorance please. But given that interface, what does the following mean? int a, b, c; string d; int i = convert_to<int>("0xff") >> std::hex >> a >> b >> c >> d;
With all due respect the interface immediately above looks (to me) more consistent and easier extendable.
That's where the get_special() method comes in. It could take any user defined function/functor for a conversion that required additional attention. However I realize that's a different sort of extensibility than what you're talking about.
Still, I am keeping an open mind on that. If something else comes up, I may well flip onto your side (the current implementation already looks nothing as what I started with showing what a "flipper" I am). :-)
I'm not married to my interface either, I was mainly just using this discussion as a sounding board. I'd like to see a really nice interface come out of it that addresses the points I made: 1. Be able to provide a default value w/o type deducing being a problem. (ie: making the interface unclear) 2. Have the same interface when used as a functor. 3. Be very explicit and clear about if you're getting throwing behavior or defaulting behavior. -- Andrew Troschinetz Applied Research Laboratories