Can someone please explain to me why in the following code I get an ambiguous call to the overloaded constructors in Foo if I attempt to instantiate MyFooC? My assumption was that the integer used as a constructor parameter would have been promoted to an unsigned int and been resolved but this is obviously incorrect.
template <typename t> class Foo
{
private:
t m_Value;
unsigned int m_Length;
public:
Foo(const t& Value) :
m_Value(Value),
m_Length(0)
{
}
Foo(unsigned int Length) :
m_Value(static_cast<t>(0)),
m_Length(Length)
{
}
};
int main()
{
Foo<double> MyFooA(32U);
Foo<double> MyFooB(32.0f);
//Foo<double> MyFooC(32);
re开发者_运维知识库turn 0;
}
An int
can be converted to both a double
and an unsigned
; both are
considered "widening" conversions, and have equal rank. As a general
rule, any time you overload, and one of the overloads is an integral
type, it's a good idea to overload on int
as well, to be sure of
getting what you want, and avoiding ambiguities, when someone tries to
pass an integral constant.
BTW: although it is clear in context what you mean, in the C++ standard,
"promotion" has a very precise meaning, and does not include a
conversion of int
to unsigned int
.
I would assume the problem is that an int could just as easily be converted to a double. I know of no specifications in C++ that dictates an order of preference for implicit casting, so when the compiler sees an int that could go to double or unsigned int, it views the call as ambiguous.
精彩评论