Boost logo

Boost :

Subject: Re: [boost] Formal Review Request: Boost.Convert
From: Emil Dotchevski (emildotchevski_at_[hidden])
Date: 2009-02-26 17:09:08


On Thu, Feb 26, 2009 at 12:42 PM, Andrey Semashev
<andrey.semashev_at_[hidden]> wrote:
> Emil Dotchevski wrote:
>
>>>> Anyway, another question: is there a way to make operator() not be a
>>>> template?
>>>
>>> It should be doable if you only need to receive the "source" argument to
>>> convert from. But if you want other arguments as well, I can't figure out
>>> how to do it without a template, unless to resort to type erasure.
>>
>> Well, one way to take arguments is to tell the compiler that your
>> function or operator() takes arguments, right?
>>
>> std::string operator()( uuid const & value, int arg1, float arg2 );
>>
>> C++ was type-safe even before templates were introduced. :)
>
> It's not about type safety, it's about making the compiler to deduce your
> intentions. How do you instruct the compiler to pass the argument with tag
> "arg1" into the second argument of your operator, and not in the first or
> third? I can only see one way to do so:
>
>  template< typename ArgsT >
>  std::string operator()( ArgsT const& args ) const
>  {
>    return operator() (args[source], args[arg1], args[arg2]);
>  }

I understand the problem very well, and I think the solution is not to
write a function that takes a single args argument, but instead to
provide overloads. This would not only solve your problem, it would
also make convert() compatible with boost::bind/function/lambda etc.

What's wrong with the following call syntax:

boost::convert<target>( source const & [,arg1,arg2,...] )

that is, the caller provides the target type for the conversion, then
the first argument is considered the source (deduced automatically),
and the rest of the arguments configure the conversion.

Going back to my uuid example, uuid.hpp could simply say:

#include <string>

namespace user {
  class uuid;
  template <class Target> Target convert( uuid const & );
  template <> std::string convert<std::string>( uuid const & );
}

(no need to include anything.)

Now, the user of uuid.hpp can also #include "boost/convert.hpp" when
making calls to convert. This could provide generic overloads that
support common conversion options, which would bind only if uuid.hpp
doesn't provide overloads itself (which would obviously be more
specialized and the overload resolution will prefer them over the
convert.hpp generics.)

Emil Dotchevski
Reverge Studios, Inc.
http://www.revergestudios.com/reblog/index.php?n=ReCode


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk