C ++和Java在处理参数多态方面有这种相似之处:两者都会将类型参数推断为常规函数或方法,但要求程序员在调用构造函数时显式给出类型参数(尽管在Java 7中已经更改了) )。
这种行为背后的技术原因是什么?
编辑:我错误地认为这也适用于Scala。 以下是Java的一个例子:
class Foo<T> {
Foo(T x) { }
}
<T> void foo(T x) { }
Foo<Integer> f = new Foo(3);
foo(3);
这两个都是合法的,但第一个创建“原始类型”而不是Foo<Integer>
,并执行未经检查的分配。
答案 0 :(得分:3)
这是因为C ++模板可以是专用的。
这意味着仅仅因为有一个主要的定义:
template<typename T>
class Foo
{
Foo(T x) { }
};
并明确地int
将被Foo<int>(int)
接受,完全有可能还有一个专门的定义
template<>
class Foo<Foobar>
{
Foo(int x) { }
};
也接受int
参数。
将用户定义的类型转换添加到混合中,您会发现无法从函数参数中找出类的类型参数。
事实上,允许对构造函数的类型参数进行推断。但不推断类模板参数。例如,在构造智能指针时允许隐式upcast:
template<typename T>
class a_smart_ptr
{
template<typename TOther>
a_smart_ptr(TOther* p) { }
};