Why can I call base template class method from derived class

Oleksiy

I decided to test one of the examples in "Effective C++" and I'm not getting the result I expected. So, apparently this (simplified) code shouldn't compile:

template <class T>
struct A {
    void f(){}
};

template <class T>
struct B : public A <T> {
    void f2() { f(); }   // calling base function - will not compile
};

Here's the explanation (class names changed for simplicity) :

The code above won't compile, at least not with conformant compilers. Such compilers will complain that f doesn't exist. We can see that f is in the base class, but compilers won't look for it there.

We need to understand why. The problem is that when compilers encounter the definition for the class template B, they don't know what class it inherits from. Sure, it's A<T>, but T is a template parameter, one that won't be known until later (when B is instantiated). Without knowing what T is, there's no way to know what the class A<T> looks like. In particular, there's no way to know if it has a f function.

My compiler (Visual Studio) doesn't mind... It doesn't even show any warnings.

Is the above code correct or not?

David Rodríguez - dribeas
template <class T>
struct A {
    void f(){}
};

template <class T>
struct B : public A <T> {
    void f2() { f(); }   // calling base function - will not compile
};

In the derived template, the expression f() is not dependent on any template argument, so the compiler attempts to resolve it during the first phase lookup. At this point, the template has not yet been instantiated with the type, and the compiler won't look into the base A<T>. The reason is that the compiler could not possibly know whether for the type of the instantiation there is a specialization of A<T> that might not contain any members.

The solution is to make the expression dependent, the simplest way would be to qualify with this->:

template <typename T>
void B<T>::f2() {  this->f(); }

As the expression is now dependent, lookup is delayed until the second phase, where the type is substituted and A<T> is a concrete type. Another alternative is qualifying with the class where it is defined:

template <typename T>
void B<T>::f2() { A<T>::f(); }

Again the expression becomes dependent and will be resolved during the second phase. The main difference is that in this second case, the call is qualified and thus it does not use dynamic dispatch. If A<T>::f() was virtual it would still execute A<T>::f(), and not the final overrider.


Is the code correct? No. Does VS accept it? Yes.

This is a known non-conformance in the Visual Studio compiler, that does not implement two phase lookup. It delays all lookup inside the template to the second phase and at that point lookup succeeds.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Can I call a derived method from base class?

From Dev

Can you add a Derived Class to a list of its base class then call a method of the Derived class from the list of base class in C#

From Dev

Can you add a Derived Class to a list of its base class then call a method of the Derived class from the list of base class in C#

From Dev

How do I call a base class method from within the same overloaded derived class method in python?

From Dev

Call derived class method from base class instance

From Dev

How to call derived class method from base class pointer?

From Dev

Call derived class method from base class instance

From Dev

Calling virtual method of base template from derived variadic template class

From Dev

How do I call a derived class method from the base class constructor in C++?

From Dev

Derived class does not call base class method

From Dev

Why can't I call an extension method from a base class of the extended type‏?

From Dev

Why can't I use alias from a base class in a derived class with templates?

From Dev

Can I forward template arguments of a derived class to the base in CRTP?

From Dev

Why can't I override the #at:put: method in a class derived from the Dictionary-class?

From Dev

Clone derived class from base class method

From Dev

Base class calls method from derived class?

From Dev

Clone derived class from base class method

From Dev

How to call constructor of a template base class in a template derived class?

From Dev

Why `this` can't access the derived class members from base class methods when called for derived class object

From Dev

Why can I not call a method from another class

From Java

Why does calling a method in my derived class call the base class method?

From Dev

In Java, why does ((A)b).disp() call derived class method disp() instead of base class method disp() ?

From Dev

Calling derived template class method from base non-template class

From Dev

Calling derived template class method from base non-template class

From Dev

Call derived method which does not exist in base class from base class

From Dev

Call derived method which does not exist in base class from base class

From Dev

Why can't we call protected destructors from a derived class?

From Dev

Calling constructor of a template base class from a template derived class

From Dev

class derived from class template using base:base in body

Related Related

  1. 1

    Can I call a derived method from base class?

  2. 2

    Can you add a Derived Class to a list of its base class then call a method of the Derived class from the list of base class in C#

  3. 3

    Can you add a Derived Class to a list of its base class then call a method of the Derived class from the list of base class in C#

  4. 4

    How do I call a base class method from within the same overloaded derived class method in python?

  5. 5

    Call derived class method from base class instance

  6. 6

    How to call derived class method from base class pointer?

  7. 7

    Call derived class method from base class instance

  8. 8

    Calling virtual method of base template from derived variadic template class

  9. 9

    How do I call a derived class method from the base class constructor in C++?

  10. 10

    Derived class does not call base class method

  11. 11

    Why can't I call an extension method from a base class of the extended type‏?

  12. 12

    Why can't I use alias from a base class in a derived class with templates?

  13. 13

    Can I forward template arguments of a derived class to the base in CRTP?

  14. 14

    Why can't I override the #at:put: method in a class derived from the Dictionary-class?

  15. 15

    Clone derived class from base class method

  16. 16

    Base class calls method from derived class?

  17. 17

    Clone derived class from base class method

  18. 18

    How to call constructor of a template base class in a template derived class?

  19. 19

    Why `this` can't access the derived class members from base class methods when called for derived class object

  20. 20

    Why can I not call a method from another class

  21. 21

    Why does calling a method in my derived class call the base class method?

  22. 22

    In Java, why does ((A)b).disp() call derived class method disp() instead of base class method disp() ?

  23. 23

    Calling derived template class method from base non-template class

  24. 24

    Calling derived template class method from base non-template class

  25. 25

    Call derived method which does not exist in base class from base class

  26. 26

    Call derived method which does not exist in base class from base class

  27. 27

    Why can't we call protected destructors from a derived class?

  28. 28

    Calling constructor of a template base class from a template derived class

  29. 29

    class derived from class template using base:base in body

HotTag

Archive