What is the reason for not overloading the C ++ transform operator with non-member functions

C ++ 0x added explicit conversion operators, but they should always be defined as members of the Source class. The same applies to the assignment operator; it must be defined in the Target class.

When the Source and Target classes of the required conversion are independent of each other, neither Source can determine the conversion operator, nor Target can determine the constructor from the Source.

We usually get it by defining a specific function, such as

Target ConvertToTarget(Source& v); 

If C ++ 0x allowed the operator of the conversion to be overloaded with non-member functions, we could, for example, define an implicit or direct conversion 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 transform like any other transform.

For a more complete description of the problem, see here or on my Boost.Conversion .

So the question is: what is the reason for not allowing the C ++ transform operator to overload with non-member functions?

+4
source share
2 answers

In accordance with the current rules, in order to decide whether you can convert between two classes, you need to look for only two places: source and target definitions. If you can define transformations as non-member functions, the transform function can be anywhere, which can make it difficult to find the cause of unwanted or ambiguous transformations (in addition to the fact that the compiler is complicated to find a possible transform in all cases where the transform was necessary or possible, for example, operator overload).

I do not think your proposed template would be very practical. Although you can explicitly specialize it for a transformation where you have a corresponding special case, it will still catch all other transformations, causing ambiguity with any pre-existing transforms.

These are perhaps two potential factors to prevent such a transformation.

+5
source

If there is no direct relationship between Source and Destination , then I want to explicitly identify the transformations between them, as with the Source sourceFromDestination(const Destination&) function Source sourceFromDestination(const Destination&) , and not be surprised at random implicit transformations.

+1
source

Source: https://habr.com/ru/post/1308294/


All Articles