0

When I was implementing a data structure, I encountered the following problem of use of undeclared identifier 'a'. Isn't an inherited from the base class? Why can't I access it?

#pragma once
#include <iostream>
template <typename T> class A {
public:
  T a;
  virtual void show() = 0;
};

template <typename T> class B : public A<T> {
public:
  B() { a = 0; }
  void show() { std::cout << "Hello, world!" << std::endl; }
};

But when I added the this pointer, there was no error message:

#pragma once
#include <iostream>
template <typename T> class A {
public:
  T a;
  virtual void show() = 0;
};

template <typename T> class B : public A<T> {
public:
  B() { this->a = 0; }
  void show() { std::cout << "Hello, world!" << std::endl; }
};

Why???

Ken White
  • 123,280
  • 14
  • 225
  • 444
Kirito
  • 1
  • 1
    See [here](https://stackoverflow.com/questions/7908248/in-a-templated-derived-class-why-do-i-need-to-qualify-base-class-member-names-w) – n. m. could be an AI Aug 28 '23 at 03:41
  • Or this: https://stackoverflow.com/a/1121016/4123703 and [C++ faq](https://isocpp.org/wiki/faq/templates#nondependent-name-lookup-members) – Louis Go Aug 28 '23 at 03:41

1 Answers1

0

When you write this->a, you are explicitly telling the compiler to look for the member a in the scope of the current instance. This helps the compiler resolve the name correctly, even in the context of templates with potential scope ambiguities.

In your first example;

B() { a = 0; }

The compiler encounters a in the constructor of class B, and it's trying to find a within the scope of class B. However, since a is inherited from class A<T>, it's considered a dependent name and requires using this-> to indicate the correct scope.

In your second example;

B() { this->a = 0; }

You are explicitly using this->a to indicate that a is a member of the current instance. This resolves the scope ambiguity and lets the compiler know that a is inherited from the base class.

Abdel
  • 404
  • 2
  • 8