为什么不能构造函数推导出模板参数?

template< class T > class Foo { public: Foo( T t ) { } }; int main () { int i = 0; Foo f( i ); } 

在上面的代码中,编译器会抱怨在'f'之前缺less模板参数。 据我所知,从构造函数的参数中推导一个类的模板参数不是标准的一部分,但我的问题是为什么? 编译器是否具有隐含地实例化Foo<int>并调用其构造函数所需的全部信息?

编辑清楚,我打电话给一个int的构造函数(而不是一个shortlongvoid*等)

因为没有人具体说明了它的工作原理。 现在有一个标准委员会的build议,使其工作。 它还列出了一些困难:

http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4471.html

更新:这是最新版本的build议:

http://open-std.org/JTC1/SC22/WG21/docs/papers/2015/p0091r0.html

TL; DR:模板专业化


他们可以,但只能在函数本身的模板参数,而不是types。

声明Foo f(0); 是非法的,因为没有名为Footypes。 也许你在想

 auto f = Foo(0); 

但是这也是不允许的,因为编译器不知道在什么范围内search(有一个名为Foo的构造函数的无限潜在types,并且可能具有多个具有构造函数Foo(int)特殊Foo(int)

通常的做法是使用工厂帮助函数:

 auto f = make_foo(0); 

工厂函数的返回types取决于参数types的扣除。


你可以想象,工厂函数可以在命名空间范围内自动生成,然后应用通常的函数重载规则,但是这会遇到很大的困难,因为在types和构造函数本身都可以有模板参数。 这些可以简单地连接起来,限制在于可以用可变参数列表排除类模板,因为没有办法区分types参数结束和函数参数开始的地方。

Foo是一个类模板 ,而不是一个类。 它的types总是需要以某种方式提供,以便使用正确的types生成类。 你不能做Foo因为Foo不是一个types,但是Foo<int>是。 它创build一个这样的类:

 class Foo { public: Foo( int t ) { } }; 

如果你只提供了Foo ,编译器将不知道如何生成类。 Foo<int> f(0)可以工作,因为Foo<int>生成类,用intreplaceT 通过你调用构造函数的types,编译器已经知道构造函数正在接受一个int

您要实例化的类的名称是Foo<int> (如您所示)。

也可以写Foo<short> f(0) ,或者Foo<unsigned long> f(0)或者Foo<Foo<double>*> f(0) 。 但是,在这些情况下,如果仅写入Foo f(0) ,则不希望编译器能够猜出types。

我们可以设想一个C ++ 可以用规则来指定,以某种方式做一些这样的猜测(例如, 0types参数int ,没有其他的代码),但是这个语言会比现在更加复杂,会有更多的方法让人们编程错误。 实际上,在这样的声明中写下你的意思似乎没有多less要求。

编辑:发布后,我注意到在另一个答案,有一个build议,使C ++的这种function,实际上是人们可以想象的。