Search code examples
c++templatesbase-classname-lookupclass-template

Simple way to reference member variables of base class templates


Is there any way to reference member variables of base class templates without base class names and scope resolution operator?

template<typename D>
struct B0 {
    int value;
};
struct D0: B0<D0> {
    D0() {
        B0<D0>::value = 1; // OK.
        value = 1;         // OK without `B0<D0>::`.
    }
};

template<typename T>
struct B1 {
    T value;
};
template<typename T>
struct D1: B1<T> {
    D1() {
        B1<T>::value = 1; // OK.
        // value = 1; // Compile error without `B1<T>::`.
                      // Compile error: use of undeclared identifier 'value'
                      // `B1<T>::` is tedious everywhere `value` is referenced.
    }
};

template<typename T, typename D>
struct B2 {
    T value;
};
template<typename T>
struct D2: B2<T, D2<T>> { // CRTP
    D2() {
        B2<T, D2<T>>::value = 1; // OK.
        // value = 1; // Compile error without `B2<T, D2<T>>::`.
                      // Compile error: use of undeclared identifier 'value'
                      // `B2<T, D2<T>>::` is more tedious for CRTP.
    }
};

int main() {
    return 0;
}

Is it possible to not write B1<T>:: or B2<T, D2<T>>:: which is tedious everywhere value is referenced?


Solution

  • As the solutions, you have to make the name value dependent to make it visible for name lookup. Besides the one you've showed, you can also:

    1. Use using to introduce the name,

      template<typename T>
      struct D1: B1<T> {
          using B1<T>::value;   // or move it in method's scope according to your intent
          D1() {
              value = 1;        // OK.
          }
      };
      
    2. Qualify with this->.

      template<typename T>
      struct D1: B1<T> {
          D1() {
              this->value = 1;  // OK.
          }
      };