1

As shown in the code, I am inheriting the class BoldPen, obtained from the template parameter to another class Writer, and creating writer1 object.

My question is regarding the 'line of interest' marked in the code below. As it stands, the code compiles fine and works. However, if I remove the PenType:: scope, changing the line to just Write the code fails compilation with error

main.cpp: In member function ‘void Writer<PenType>::StartWriting()’:
main.cpp:17:11: error: there are no arguments to ‘Write’ that depend on a template parameter, so a declaration of ‘Write’ must be available [-fpermissive]
     Write();
           ^

From my understanding, shouldn't it compile fine since the BoldPen class is being inherited by Writer, which means it should see the Write method in its superclass BoldPen? Why is PenType:: (I can see it useful if it were static member function, in which case there is no point (?) in inheriting it )

#include <iostream>

struct BoldPen
{
  void Write()
  {
    std::cout << "Writing using a boldpen" << std::endl;
  }
};

template<class PenType>
class Writer : public PenType
{
public:
  void StartWriting()
  {
    PenType::Write();     //#####LINE OF INTEREST##### Gives error when just Write();
  }
};

int main()
{

  Writer<BoldPen> writer1;
  writer1.StartWriting();
  return 0;
}

EDIT:

Although the linked question (duplicate of) does answer the core reason behind it, I am more concerned with its effect on member functions after the inheritance is completed. Particularly, the syntax used is quite similar to how one would access static methods. Does that go well with dependent name lookup?Also see the comments for further info. Thanks.

User 10482
  • 855
  • 1
  • 9
  • 22
  • 2
    The compiler looks for a standalone function named `Write()`, as it has no reason to assume that one might hide inside `PenType`. `PenType::Write()` is one way to make it look there; `this->Write()` is another. Formally, when you have just `Write()`, `Write` is not a dependent name and is looked up at the point of themplate definition. `PenType::Write()` makes it a dependent name, looked up at the point of instantiation (where it is known that `PenType` is in fact `BoldPen`). – Igor Tandetnik Aug 20 '19 at 03:42
  • @Igor Tandetnik Wouldn't it have a standalone ```Write()``` function since it's inheriting from the ```PenType``` class. ```BoldPen``` class it's inheriting from is a non-template as well. – User 10482 Aug 20 '19 at 13:09
  • Oh, I think I understand what you mean. PenType can practically be any other class which might not have a ```Write( )``` method. So it's safer for the compiler to assume no such method exists, unless explicitly told and guaranteed by the programmer by the scope prefix ```PenType::```. Am I on the right track here? Also what would happen after the inheritance though? Isn't it semantically wrong to access ```BoldPen::Write()``` since the method is not static? – User 10482 Aug 20 '19 at 14:00
  • `BaseClass::MethodName()` is a perfectly fine syntax, templates or no templates. Used all the time, e.g. from an override of a virtual member function to call base class implementation. As in `void Derived::f() override { Base::f(); DoSomethingMore(); }` – Igor Tandetnik Aug 20 '19 at 14:45

0 Answers0