Question

C++ and Java have this similarity in how they handle parametric polymorphism: both will infer the type parameters to regular functions or methods, but require the programmer to explicitly give the type parameters when calling a constructor (Though this was changed in Java 7).

What is the technical reason behind this behavior?

edit: I mistakenly thought this applied to Scala as well. Here is an example from Java:

class Foo<T> {
    Foo(T x) { }
}

<T> void foo(T x) { }


Foo<Integer> f = new Foo(3);
foo(3);

both of these are legal, but the first one creates a "raw type" rather than a Foo<Integer>, and performs an unchecked assignment.

Was it helpful?

Solution

It's because C++ templates can be specialized.

That means that just because there's a main definition:

template<typename T>
class Foo
{
    Foo(T x) { }
};

and clearly int will be accepted by Foo<int>(int), it's completely possible that there's also a specialized definition

template<>
class Foo<Foobar>
{
    Foo(int x) { }
};

which also accepts an int parameter.

Add user-defined type conversions to the mix, and you see that it just isn't possible to figure out the class's type parameters from function arguments.

And in fact, inference of type parameters for constructors IS allowed. But not inference of the class template parameters. For example, allowing implicit upcast when constructing a smart pointer:

template<typename T>
class a_smart_ptr
{
    template<typename TOther>
    a_smart_ptr(TOther* p) { }
};
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top