Hi there,
I have a problem understanding how ambiguity is resolved or when it is reported in implicit (i.e. compiler deduced) conversions that involve class-type conversions. I am aware of few rules involved in implicit conversions but some cases I cannot explain. I am using Microsoft's C++ compiler in VS 2013.
As you know if a function parameter and the corresponding argument from a function call do not match the compiler will try to do an implicit conversion. If either the parameter or the argument is a built-in type and the other is a class-type then the implicit conversion sequence may include a function composition of a class-type conversion and a built-in conversion. Let's consider the following example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
#include <iostream>
using namespace std;
class MyInt
{
public:
operator int() { cout << "conversion from MyInt to int" << endl; return val; }
operator double() { cout << "conversion from MyInt to double" << endl; return val; }
private:
std::size_t val;
};
void compute(int x) { cout << "inside compute(int)" << endl; }
void main()
{
MyInt obj;
compute(obj);
}
|
This example illustrates having two class-type conversion functions. Considering the declarations the situation is the following:
SmallInt -> int -> int
SmallInt -> double -> int
NON-AMBIGUITY -> first used
The compiler successfully compiles the program. From the program's output we see that the first conversion function is used. It is important to understand that in this case both conversion functions can be used, but in the first case only one class-type conversion function is used (SmallInt -> int) and in the second case both a class-type conversion function (SmallInt -> double) and a built-in conversion (double -> int) are used. Thus the compiler resolves the ambiguity by choosing the first conversion. The first rule is thus that a conversion involving a class-type conversion function is better than another one involving both a class-type conversion function and a built-in conversion.
If we change the declaration(s) in the program to have this situation:
SmallInt -> int -> long int
SmallInt -> double -> long int
AMBIGUITY
the program does not compile. In this case both conversion sequences contain both a class-type and a standard (built-in) conversion which the compiler considers equally good thus it reports ambiguity.
The same is the case in this:
SmallInt -> int -> long double
SmallInt -> double -> long double
AMBIGUITY
What puzzles me are the following cases:
1)
SmallInt -> long int -> int
SmallInt -> double -> int
NON-AMBIGUITY -> first used
- In both cases we have a class-type and a standard conversion!?! Why is the first better?
2)
SmallInt -> unsigned long int -> int
SmallInt -> double -> int
AMBIGUITY
- If the case 1 (long) is unambiguous why is this one (unsigned long) ambiguous?
3)
SmallInt -> short int -> int
SmallInt -> double -> int
NON-AMBIGUITY -> first used
- Is this maybe because the rank of the built-in conversion in the first case (short int -> int) - standard promotion - is better than the rank of the built-in conversion in the second case (double -> int)? If this is true then I am puzzled that the rank of built-in conversions is considered at all since in this case we have two DIFFERENT class-type conversions. I want to remind you that in a related but different issue - function overload resolution - there is a rule which says: If two functions in the overload set can be matched using THE SAME class-type conversion function, then the rank of the standard conversion that follows or precedes the class-type conversion is used to determine which function has the better match. Otherwise, if DIFFERENT class-type conversion operations could be used, then the conversions are considered equally good matches, regardless of the rank of any standard conversions that might or might not be required.
4)
SmallInt -> short int -> int
SmallInt -> signed char -> int
AMBIGUITY
Can anyone give me an explanation for this? I would very much appreciate a reference to a paragraph(s) in the ISO/IEC C++ standard.
best regards