简体   繁体   中英

Calling method of template base class

The following code compiles in visual studio 2015 (even with /Za option). It doesn't compile on gcc and 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 - error: 'template struct B' used without template parameters
clang - error: 'B' is not a class, namespace, or enumeration

Which compiler is compliant to standard specifications? Any ambiguity in the specs?

Edit
I've added f() in C to have a more pertinent example.

Normally to call a base class function in this case you would write:

this->f();

If f and g were both static, you would of course not be able to do this, so instead you could write

B<T>::f();

This works because B is already in scope at the declaration of C , so the compiler already knows it's a template. If you do B::f() alone, the compiler will give you an error because it knows B is a template so it is supposed to have template arguments.

You might be wondering why you are allowed to omit the template arguments inside the definition of B<T> but not inside the definition of C . To understand this, you need to know that every class has an injected-class-name that behaves like a typedef declared at the very beginning of the class definition. So it is as though the definition of B started with

typedef B<T> B;

Using B inside the definition of B<T> will find the injected-class-name , not the template. But when you are inside C , this B is not visible since it is declared inside B<T> , which is a dependent base class, and dependent base class scopes are not searched during unqualified name lookup (and B is on the left of :: , so the lookup of B is unqualified). This also works:

C::B::f();

In this case, the injected-class-name C is found, and it refers to the dependent type C<T> , so the lookup of B will search inside the dependent base class B<T> and find the desired injected-class-name .

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

The compiler doesn't know the B you're referring to in B::f(); , try changing it to B<T>::f(); .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM