Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this-> mandatory to access Base<T> identifiers from derived classes?

This code compiles with MSVC 2015, but doesn't compile with Clang 5.0.0 (trunk 304874):

template <typename T> struct Base {   T data; };  template <typename T> struct Derived : Base<T> {   auto getData() const   {     return data;   } }; 

Replacing data with this->data in Derived::getdata() makes Clang happy.

Which compiler is correct according to the C++ standard?

Must this-> be used in template code to access an identifier of a base class?

like image 718
Mr.C64 Avatar asked Jun 07 '17 15:06

Mr.C64


People also ask

When a class is derived from a base class it gets access to?

A derived class can access all the non-private members of its base class. Thus base-class members that should not be accessible to the member functions of derived classes should be declared private in the base class. Constructors, destructors and copy constructors of the base class.

Can base class access derived class members C++?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

What does derived class inherit from the base class?

The derived class inherits all members and member functions of a base class. The derived class can have more functionality with respect to the Base class and can easily access the Base class. A Derived class is also called a child class or subclass.

What members of a base class can be defined in the derived classes?

A base class member function may be redefined in a derived class. CONCEPT: A base class member function may be redefined in a derived class.


2 Answers

Clang is correct.

$17.6.2/3 Dependent names [temp.dep]

In the definition of a class or class template, the scope of a dependent base class is not examined during unqualified name lookup either at the point of definition of the class template or member or during an instantiation of the class template or member.

For return data;, data is unqualified, then unqualified name lookup will be employed. This means the name in the base class Base<T> (which is a dependent base class because it depends on the template parameter T) shouldn't be found; i.e. the non-dependent names are not looked up in dependent base classes.

this->data or Base<T>::data makes it qualified. This means the name will be looked up at the time of instantiation, and at that time the exact base specialization that must be explored will be known.

like image 96
songyuanyao Avatar answered Oct 25 '22 13:10

songyuanyao


Yes, it is. Basically data depends on T.

There is a mechanism called two-phase lookup. Non-(template)dependent names are resolved immediately - at the point of definition. Your data does not exist yet, because Base<T> does not exist yet, as it was not instantiated. Thus, it complains that data is not found.

You need to hint compiler that data depends on the template, and the name lookup should be performed in the second phase, after template parameters are substituted, i.e. template class was instantiated. This can be done by using this or providing template dependent scope.

So, either this->f() or Base<T>::f() will work.

like image 27
luk32 Avatar answered Oct 25 '22 13:10

luk32