2010-06-10 112 views
2

为什么下面的代码无效?使用模板参数作为模板参数

template <typename S, typename T> 
struct B{ 
    void f(T t, S s) {t.f<S>(s); } 
}; 

GCC 4.3.4抱怨说,它的“预期之前‘>’令牌主表达式”,即该“S”不是有效的基本表达式。

回答

12

你需要指定f是一个模板:

void f(T t, S s) { 
    t.template f<S>(s); 
} 

C++不知道这(在这一点上),因为f的类型取决于模板参数T的类型。此外,下面的语法不明确:<是指模板列表或小于运算符的开始吗?为了帮助C++数字,你需要指定f是一个模板,否则C++不能解析下面的部分,因为解析自己取决于T的类型。

+0

VS可以解析它(懒惰解析?),它只是一个C++标准限制 – coyotte508 2011-09-21 14:10:46

+0

@ coyotte508 VS使用双路解析器来处理这个问题。这当然是可能的,但效率很低。标准中一次通过的限制很有意义,特别是考虑到计算机并不总是像现在一样快,而C++编译器仍然*速度很慢。 – 2011-09-21 15:36:30

+0

这很了解。这不是GCC以这种方式表现的唯一实例(如果BaseClass是模板参数,它需要使用BaseClass :: function),所以personnally我不介意交易一些编译时间,但我现在明白为什么限制。 – coyotte508 2011-09-21 15:52:00

1

您还可以依靠类型推断来推断模板类型,而不是明确指出它。然后你会得到“tf(s);”,它实际上是一种稍微更通用的方式来陈述它:你可能不关心f是一个模板函数,你只是希望它为f定义一个接受S.

+0

由于多态性,我认为类型推断在实际代码中会失败。 f看起来像模板 void f(S&),我想实例化f (Child&),这在示例代码中是不清楚的。 – 2010-06-11 20:39:14