简体   繁体   中英

Why user-defined conversions are limited?

In C++, only one user-defined conversion is allowed in implicit conversion sequence. Are there any practical reasons (from language user point of view) for that limit?

Allowing only one user defined conversion limits the search scope when attempting to match the source and destination types. Only those two types need to be checked to determine whether they are convertible (non-user defined conversions aside).

Not having that limit might cause ambiguity in some cases and it might even require testing infinite conversion paths in others. Since the standard cannot require to do something unless it is impossible to do in your particular case , the simple rule is only one conversion .

Consider as a convoluted example:

template <typename T>
struct A {
   operator A<A<T>> () const;  // A<int> --> A<A<int>>
};

int x = A<int>();

Now, there can potentially be a specialization for A<A<A<....A<int>...>>> that might have a conversion to int , so the compiler would have to recursively instantiate infinite versions of A and check whether each one of them is convertible to int .

Conversely, with two types that are convertible from-to any other type, it would cause other issues:

struct A {
   template <typename T>
   A(T);
};
struct B {
   template <typename T>
   operator T() const;
};
struct C {
   C(A);
   operator B() const;
};

If multiple user-defined conversions where allowed, any type T can be converted to any type U by means of the conversion path: T -> A -> C -> B -> U. Just managing the search space would be a hard task for the compiler, and it would most probably cause confusion on the users.

IMHO It is a design choice based on the fact that constructors are not explicit by default. Which is a practical reason for setting a limit, to disallow the following expression to be valid.

  objectn o = 5; 
  5-> object1(5)->object2(object1)->object3(object2)->...->objectn(objectn-1)

Each arrow above is an implicit conversion.
One seems to be a reasonable choice.If more are allowed, you have several implicit conversion paths between an object0 and objectn . Each one leading to possibly different objectn o. Which one to choose??

If it allows more than one, then how many in the sequence? If infinite, then wouldn't it make too complicated for a large number of types in a large project? For example, everytime you add implicit conversion, you have to think really really hard as to what else it converts into and then what else that converts into? and the chain goes on. Very dangerous situation, IMHO.

Implicit conversions (what is currently allowed by the language) are considered bad, which is why C++11 has added contextual conversion which is implemented using explicit keyword.

If the allowed number were infinite, you could quite quickly end up with an attempted circular conversion sequence.

It's much easier to say "if you need more than one conversion, you have a design flaw" and use that rationale to emplace a bug-saving limit within the language.

In any case, implicit conversions are generally considered to be best when used sporadically . One conversion is very useful for the sort of heavy operator overloading used by the standard library, and similar code; beyond that, there's not much excuse to ever use implicit conversions. Certainly a language would go in the direction of seeking fewer, not more (eg C++11 adding explicit in this context, to help you enforce no implicit conversions at all ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM