为什么不能构造函数推导出模板参数?
template< class T > class Foo { public: Foo( T t ) { } }; int main () { int i = 0; Foo f( i ); }
在上面的代码中,编译器会抱怨在'f'之前缺less模板参数。 据我所知,从构造函数的参数中推导一个类的模板参数不是标准的一部分,但我的问题是为什么? 编译器是否具有隐含地实例化Foo<int>
并调用其构造函数所需的全部信息?
编辑清楚,我打电话给一个int
的构造函数(而不是一个short
, long
, void*
等)
因为没有人具体说明了它的工作原理。 现在有一个标准委员会的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);
是非法的,因为没有名为Foo
types。 也许你在想
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>
生成类,用int
replaceT
通过你调用构造函数的types,编译器已经知道构造函数正在接受一个int
。
您要实例化的类的名称是Foo<int>
(如您所示)。
也可以写Foo<short> f(0)
,或者Foo<unsigned long> f(0)
或者Foo<Foo<double>*> f(0)
。 但是,在这些情况下,如果仅写入Foo f(0)
,则不希望编译器能够猜出types。
我们可以设想一个C ++ 可以用规则来指定,以某种方式做一些这样的猜测(例如, 0
types参数int
,没有其他的代码),但是这个语言会比现在更加复杂,会有更多的方法让人们编程错误。 实际上,在这样的声明中写下你的意思似乎没有多less要求。
编辑:发布后,我注意到在另一个答案,有一个build议,使C ++的这种function,实际上是人们可以想象的。