调用模板基类的方法

时间:2016-03-18 22:17:30

标签: c++ gcc visual-c++ visual-studio-2015 clang

以下代码在visual studio 2015中编译(即使使用/ Za选项)。它不能在gcc和clang上编译。

struct A
{
};

template<typename T>
struct B
{
  void f()
  {
  }
};

template<typename T>
struct C : B<T>
{
  void f()
  {
  }

  void g()
  {
    B::f();
  }
};

int main()
{
  C<A> c;
  c.g();

  return 0;
}

Demo

gcc - 错误:'模板结构B'没有模板参数使用
clang - 错误:'B'不是类,命名空间或枚举

哪种编译器符合标准规范?规格中有任何含糊之处吗?

修改
我在f()中添加了C以获得更相关的示例。

3 个答案:

答案 0 :(得分:4)

通常在这种情况下调用基类函数,你会写:

this->f();

如果fg都是静态的,那么你当然无法做到这一点,所以你可以写一下

B<T>::f();

这是有效的,因为B已经在C的声明范围内,因此编译器已经知道它是一个模板。如果你单独B::f(),编译器会给你一个错误,因为它知道B是一个模板,所以它应该有模板参数。

您可能想知道为什么允许您在B<T>的定义中省略模板参数,但不在C的定义中。要理解这一点,您需要知道每个类都有一个 inject-class-name ,其行为类似于在类定义的最开始声明的typedef。所以好像B的定义以

开头
typedef B<T> B;

B的定义中使用B<T>会找到 inject-class-name ,而不是模板。但是当你在C内时,这个B是不可见的,因为它是在B<T>内声明的,它是一个从属基类,并且在非限定名称查找期间不会搜索依赖的基类范围(B位于::的左侧,因此B的查找不合格。这也有效:

C::B::f();

在这种情况下,找到了注入类名 C,它引用了依赖类型C<T>,因此B的查找将在依赖基类B<T>内搜索并找到所需的注入类名

答案 1 :(得分:1)

问题出在struct C,来自f的函数B在没有模板参数的情况下被调用。

答案 2 :(得分:0)

编译器不知道您在B中引用的B::f();,请尝试将其更改为B<T>::f();