C++0x has added explicit conversion operators, but they must always be defined as members of the Source class. The same applies to the assignment operator, it must be defined on the Target class.
When the Source and Target classes of the needed conversion are independent of each other, neither the Source can define a conversion operator, neither the Target can define a constructor from a Source.
Usually we get it by defining a specific function such as
Target ConvertToTarget(Source& v);
If C++0x allowed to overload conversion operator by non member functions we could for example define the conversion implicitly or explicitly between unrelated types.
template < typename To, typename From >
operator To(const From& val);
For example we could specialize the conversion from chrono::time_point to posix_time::ptime as follows
template < class Clock, class Duration>
operator boost::posix_time::ptime(
const boost::chrono::time_point<Clock, Duration>& from)
{
using namespace boost;
typedef chrono::time_point<Clock, Duration> time_point_t;
typedef chrono::nanoseconds duration_t;
typedef duration_t::rep rep_t;
rep_t d = chrono::duration_cast<duration_t>(
from.time_since_epoch()).count();
rep_t sec = d/1000000000;
rep_t nsec = d%1000000000;
return posix_time::from_time_t(0)+
posix_time::seconds(static_cast<long>(sec))+
posix_time::nanoseconds(nsec);
}
And use the conversion as any other conversion.
For a more complete description of the problem, see here or on my Boost.Conversion library..
So the question is: What is the rationale to non allow overloading of C++ conversions operator with non-member functions?
When operator overloading is achieved using non-member function there are two cases to be considered: the overloaded operator uses only the public interface of the class(es) involved in the overloading, or. the overloaded operator requires access to the private data of the class(es).
Not mentioned in the question but there are also operator which can't be overloaded at all: The member selector .
Which operator can only be overloaded as a class member function. C++ operators can be overloaded as a class member or non-member functions.
It allows you to provide an intuitive interface to users of your class, plus makes it possible for templates to work equally well with classes and built-in/intrinsic types. Operator overloading allows C/C++ operators to have user-defined meanings on user-defined types (classes).
With the current rules, to work out whether you can convert between two classes you only need to look in two places: the source and target definitions. If you could define conversions as non-member functions the conversion function could be anywhere which might make finding the cause of unwanted or ambiguous conversions much more difficult (in addition to making the compiler work harder to find possible conversion in all cases where a conversion was need or possible e.g. operator overloading).
I don't think that your proposed template would be very practical. Although you could explicitly specialize it for conversion where you did have an appropriate special case, it would still catch all other conversions causing ambiguities with any pre-existing conversions.
These are perhaps two potential factors in not allowing such conversion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With