Elsa FAQ

Elsa Frequently Asked Questions

This page has answers to questions that I've received and think might be useful generally.

# Contents

- 1. Why can't Elsa find names in template base classes?

# 1. Why can't Elsa find names in template base classes?

Given the input:

      // foo.cc

      template <class T>
      class Base {
      public:
        int x;
      };

      template <class T>
      class Derived : public Base<T> {
      public:
        int get_x() {
          return x;            // line 13
        }
      };

Elsa (invoked via ccparse) says:

      foo.cc:13:12: error: there is no variable called `x' (from template; would be suppressed in permissive mode)
      typechecking results:
        errors:   1
        warnings: 0

The reason Elsa rejects this input is that it is doing what is usually called "two phase lookup", officially known as non-dependent name resolution, in template bodies. These rules are specified in the C++ Standard, section 14.6.

Basically, since the name `x` does not appear to depend on the template arguments, it is looked up at the time the template definition is being processed. Further, at definition time, we cannot know which specialization of `Base` will be used (since that is dependent on the template arguments), so none of the names from `Base` are visible. Consequently, no declaration for `x` can be found.

As the diagnostic indicates, this error is suppressed in permissive mode (say `-tr permissive` to `ccparse`) for compatibility with gcc prior to version 3.4.

To fix the code, change it to:

        int get_x() {
          return this->x;            // line 13
        }

This change has the effect of making `x` depend on the template arguments (since `this` inside a template class is considered dependent), and hence lookup of `x` will be delayed until the template is instantiated, at which point we will know which `Base` will be used and can therefore look inside it. Assuming the `Base` used is the one shown above, `x` will then be found.