9

我试图弄清楚为什么一些我没有编译的代码,我做了一些减少匿名化以结束这个例子的原因:

#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 version 4.0 (tags/Apple/clang-421.0.57) (based on 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 ‘&gt;’ token
tmp.cpp:18: error: expected primary-expression before ‘)’ token

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

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

如果这是一个编译器错误(似乎值得怀疑),有没有人知道任何不涉及将 amem 转换为带有 bool 参数(而不是模板)的函数的解决方法?我已经这样做了,我可以确认这可以解决这个问题,但这是在一个热循环中,并且由 b 打开的代码是一个可能不应该处于热循环中的内存分配。

4

2 回答 2

26

需要添加template关键字:

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

请阅读我必须在哪里以及为什么要放置“模板”和“类型名称”关键字?进行深入的解释。

于 2012-11-11T23:43:46.453 回答
3

在您调用的上下文中

return ap->amem<b>();

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

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

顺便说一句,请注意,您不得定义NULL!如果你需要一个可憎的定义,你应该包括,例如,cstddef。最好只使用0nullptr在使用 C++ 2011 时使用。

于 2012-11-11T23:48:21.480 回答