首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++模板陷阱

C++模板陷阱
EN

Stack Overflow用户
提问于 2009-12-10 07:26:58
回答 4查看 5.5K关注 0票数 23

刚才我不得不深入网站找出为什么模板类模板成员函数会给出语法错误:

代码语言:javascript
复制
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

代码语言:javascript
复制
f.template bar<T>();

你遇到过的C++/C++模板的其他奇怪的方面和陷阱是不是你认为是常识的?

EN

回答 4

Stack Overflow用户

发布于 2009-12-10 14:59:12

当我第一次从另一个模板类继承模板类时,我遇到了问题:

代码语言:javascript
复制
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指令告诉编译器它将在那里:

代码语言:javascript
复制
template<typename T>
class Derived : public Base<T> {
    using Base<T>::a;
    void func() {
        a++; // OK!
    }
};

或者,您可以明确表示您正在使用T的成员

代码语言:javascript
复制
void func {
    T::a++; // OK!
}
票数 14
EN

Stack Overflow用户

发布于 2009-12-10 07:38:49

这一条当时让我很不爽:

代码语言:javascript
复制
#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::vectorfoo::vector。要修复此问题,您必须编写

代码语言:javascript
复制
f.foo::vector<int>();

GCC并不关心这一点,他通过做直观的事情(调用成员)接受了上面的代码,其他编译器做得更好,并像comeau一样发出警告:

代码语言:javascript
复制
"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!
票数 8
EN

Stack Overflow用户

发布于 2010-09-22 15:39:26

关于模板的问题之星在SO上:缺少的typename!

代码语言:javascript
复制
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中所述。

代码语言:javascript
复制
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
}
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1877687

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档