刚才我不得不深入网站找出为什么模板类模板成员函数会给出语法错误:
template<class C> class F00 {
template<typename T> bar();
};
...
Foo<C> f;
f.bar<T>(); // syntax error here我现在意识到模板括号被视为关系运算符。要执行预期的操作,需要使用以下奇怪的语法: cf Templates: template function not playing well with class's template member function
f.template bar<T>();你遇到过的C++/C++模板的其他奇怪的方面和陷阱是不是你认为是常识的?
发布于 2009-12-10 14:59:12
当我第一次从另一个模板类继承模板类时,我遇到了问题:
template<typename T>
class Base {
int a;
};
template<typename T>
class Derived : public Base<T> {
void func() {
a++; // error! 'a' has not been declared
}
};问题是编译器不知道Base<T>是默认模板还是专用模板。专用版本可能没有int a作为成员,因此编译器不会假定它是可用的。但是您可以通过using指令告诉编译器它将在那里:
template<typename T>
class Derived : public Base<T> {
using Base<T>::a;
void func() {
a++; // OK!
}
};或者,您可以明确表示您正在使用T的成员
void func {
T::a++; // OK!
}发布于 2009-12-10 07:38:49
这一条当时让我很不爽:
#include <vector>
using std::vector;
struct foo {
template<typename U>
void vector();
};
int main() {
foo f;
f.vector<int>(); // ambiguous!
}main中的最后一行是不明确的,因为编译器不仅在foo中查找vector,而且还从main中开始查找非限定名称。因此,它可以同时找到std::vector和foo::vector。要修复此问题,您必须编写
f.foo::vector<int>();GCC并不关心这一点,他通过做直观的事情(调用成员)接受了上面的代码,其他编译器做得更好,并像comeau一样发出警告:
"ComeauTest.c", line 13: warning: ambiguous class member reference -- function
template "foo::vector" (declared at line 8) used in preference to
class template "std::vector" (declared at line 163 of
"stl_vector.h")
f.vector<int>(); // ambiguous!发布于 2010-09-22 15:39:26
关于模板的问题之星在SO上:缺少的typename!
template <typename T>
class vector
{
public:
typedef T * iterator;
...
};
template <typename T>
void func()
{
vector<T>::iterator it; // this is not correct!
typename vector<T>::iterator it2; // this is correct.
}这里的问题是vector<T>::iterator是一个依赖名称:它依赖于模板参数。因此,编译器不知道iterator指定了一个类型;我们需要用typename关键字告诉他。
模板内部类或模板成员/静态函数也是如此:必须使用template关键字消除它们的歧义,如OP中所述。
template <typename T>
void func()
{
T::staticTemplateFunc<int>(); // ambiguous
T::template staticTemplateFunc<int>(); // ok
T t;
t.memberTemplateFunc<int>(); // ambiguous
t.template memberTemplateFunc<int>(); // ok
}https://stackoverflow.com/questions/1877687
复制相似问题