Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguity between overloaded constructors

Tags:

c++

templates

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);
    return 0;
}
like image 861
Munro Avatar asked Sep 15 '11 12:09

Munro


1 Answers

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.

like image 162
James Kanze Avatar answered Sep 18 '22 19:09

James Kanze