在模板类中调用模板方法

时间:2012-11-11 23:42:10

标签: c++ templates

我试图找出为什么我的某些代码无法编译,并且我做了一些减少匿名化以结束这个例子:

#define NULL ((void*)0)
template<typename T>
class a {
public:
  template<bool b>
  T * amem() {
    return NULL;
  }
};

template<typename T>
class b {
public:
  a<T>* ap;

  template <bool b>
  T * m() {
    return ap->amem<b>();
  }
};

int main()
{
  return 0;
}

根据我使用的编译器和变量的名称,我会得到不同的错误。尽管如此,它们都围绕着这条线:

    return ap->amem<b>();

使用clang ++进行编译[Apple clang 4.0版(标签/ Apple / clang-421.0.57)(基于LLVM 3.1svn)],我收到以下消息:

tmp.cpp:18:26: error: expected expression
      return ap->amem<b>();
                         ^
1 error generated.

使用g ++编译[i686-apple-darwin11-llvm-g ++ - 4.2(GCC)4.2.1],我收到以下消息:

tmp.cpp: In member function ‘T* b<T>::m()’:
tmp.cpp:18: error: expected primary-expression before ‘>’ token
tmp.cpp:18: error: expected primary-expression before ‘)’ token

神秘(对我来说,无论如何)。如果我将amem的名称更改为m,我不再从g ++中得到任何错误,但是我从clang ++中得到了同样的错误。

我确定这里有些东西我不明白?有谁知道clang和gcc正在寻找什么表达?有谁知道如何解决这个问题?

如果这是一个编译器错误(看起来很可疑),有没有人知道任何不涉及将amem转换为带有bool参数的函数(而不是模板)的变通方法?我已经完成了这个,我可以确认这可以解决问题,但这是在一个热循环中,由b打开的代码是一个内存分配,可能不应该在热循环中。

2 个答案:

答案 0 :(得分:19)

需要添加template关键字:

return ap->template amem<b>();

请阅读Where and why do I have to put the “template” and “typename” keywords?以获得深入的解释。

答案 1 :(得分:3)

在您调用的上下文中

return ap->amem<b>();

名称amem是一个从属名称:如果这样的野兽确实是指成员函数模板,则需要通过添加关键字template来说明:

return ap->template amem<b>();
顺便说一句,请注意你不会定义NULL!如果您需要定义憎恶,则应包括cstddef。在使用C ++ 2011时,最好只使用0nullptr