为什么构造函数ä¸èƒ½æŽ¨å¯¼å‡ºæ¨¡æ¿å‚数?

时间:2015-04-16 14:18:51

标签: c++

template< class T >
class Foo {
public:
  Foo( T t ) { }
};

int main () {
  int i = 0;
  Foo f( i );
}

在上é¢çš„代ç ä¸­ï¼Œç¼–译器抱怨在f&#39;之å‰ç¼ºå°‘模æ¿å‚数。我ç†è§£ä»Žæž„造函数的å‚数中推导出类的模æ¿å‚æ•°ä¸æ˜¯æ ‡å‡†çš„一部分,但我的问题是为什么?编译器是å¦å…·æœ‰éšå¼å®žä¾‹åŒ–Foo<int>并调用其构造函数所需的所有信æ¯ï¼Ÿ

修改åŽæ˜Žç¡®è¡¨ç¤ºæˆ‘使用int(而ä¸æ˜¯short,long,void*ç­‰æ¥è°ƒç”¨æž„造函数。)

4 个答案:

答案 0 :(得分:35)

因为没有人说明具体如何。目å‰å‘标准委员会æ出了使其有效的建议。它还列出了一些困难:

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

更新:这是该æ案的最新版本:

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

答案 1 :(得分:18)

TL; DR:模æ¿ä¸“业化


它们å¯ä»¥ï¼Œä½†åªæœ‰å‡½æ•°æœ¬èº«çš„模æ¿å‚数,而ä¸æ˜¯ç±»åž‹ã€‚

声明Foo f(0);是éžæ³•çš„,因为没有å为Foo的类型。也许你在考虑

auto f = Foo(0);

但也ä¸å…许这样åšï¼Œå› ä¸ºç¼–译器ä¸çŸ¥é“è¦æœç´¢çš„范围(有无é™çš„潜在类型,带有å为Foo的构造函数,并且具有特化,å¯èƒ½ä¸æ­¢ä¸€ä¸ªå¸¦æœ‰æž„造函数{ {1}})

执行此æ“作的常用方法是使用工厂辅助函数:

Foo(int)

其中工厂函数的返回类型å–决于其å‚数的类型推导。


您å¯ä»¥æƒ³è±¡å·¥åŽ‚函数å¯ä»¥åœ¨å‘½å空间范围内自动生æˆï¼Œç„¶åŽåº”用通常的函数é‡è½½è§„则,但这会é‡åˆ°å¾ˆå¤§çš„困难,因为类型和构造函数本身都å¯ä»¥æœ‰æ¨¡æ¿å‚数。这些å¯ä»¥ç®€å•åœ°è¿žæŽ¥èµ·æ¥ï¼Œä½†æ˜¯è¿™ä¼šé™åˆ¶å…·æœ‰å¯å˜å‚数列表的类模æ¿ï¼Œå› ä¸ºæ²¡æœ‰åŠžæ³•åŒºåˆ†ç±»åž‹å‚数的结æŸå’Œå‡½æ•°å‚数的开始。

答案 2 :(得分:8)

Foo是一个模æ¿ï¼Œè€Œä¸æ˜¯ä¸€ä¸ªç±»ã€‚它的类型总是需è¦ä»¥æŸç§æ–¹å¼æ供,以便使用正确的类型生æˆç±»ã€‚您无法执行Foo因为Fooä¸æ˜¯ç±»åž‹ï¼Œä½†æ˜¯Foo<int>。它创建了一个这样的类:

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

如果您åªæä¾›Foo,编译器将ä¸çŸ¥é“如何生æˆè¯¥ç±»ã€‚ Foo<int> f(0)有效,因为Foo<int>生æˆäº†ç±»ï¼Œç”¨T替æ¢int。根æ®æ‚¨è°ƒç”¨æž„造函数的类型,编译器已ç»çŸ¥é“构造函数正在接å—int。

答案 3 :(得分:5)

è¦å®žä¾‹åŒ–的类的å称是 Foo<int>(如您所示)。

也å¯ä»¥å†™Foo<short> f(0)或Foo<unsigned long> f(0), 或Foo<Foo<double>*> f(0)。但是,在这些情况下,如果åªç¼–写Foo f(0),则ä¸å¸Œæœ›ç¼–译器能够猜出类型。

å¯ä»¥æƒ³è±¡ï¼ŒC ++ å¯ä»¥æŒ‡å®šäº†è¦åˆ¶ä½œçš„规则 一些这样的猜测在æŸäº›æ–¹é¢ï¼ˆä¾‹å¦‚,文字0暗示类型å‚æ•°int而ä¸æ˜¯å…¶ä»–),但éšåŽè¯­è¨€ä¼šæ›´å¤š 比现在å¤æ‚,还有其他的方法 人们编程错误。 实际上在这样的声明中写下你的æ„æ€ ä¼¼ä¹Žæ²¡æœ‰å¤ªå¤šè¦é—®ã€‚

修改:å‘布此内容åŽï¼Œæˆ‘在å¦ä¸€ä¸ªå›žç­”中注æ„到是 æ出了制作C ++这样一个功能的建议,确实å¯ä»¥æƒ³è±¡ã€‚