Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

template base class typedef members invisible

I'm aware of the fact that the 'dependent names' are not visible to the compiler by default. But I was told in answers to other SO questions (here, here, and ultimately on the C++ faq) that a using declaration may help.

So I tried.

A template base class:

// regardless of the fact that members are exposed...
template<typename T>
struct TBase {
   typedef T MemberType;
   MemberType baseMember;
   MemberType baseFunction() { return MemberType(); }
};

And a derived class, using the base's members:

template<typename T>
struct TDerived : public TBase<T> {
   // http://www.parashift.com/c++-faq-lite/nondependent-name-lookup-members.html
   // tells us to use a `using` declaration.
   using typename TBase<T>::MemberType;
   using TBase<T>::baseFunction;
   using TBase<T>::baseMember;

   void useBaseFunction() { 
      // this goes allright.
      baseFunction();
      ++baseMember;

      // but here, the compiler doesn't want to help...
      MemberType t; //error: expected `;' before ‘t’
   }
};

I tried this out on ideone. It has gcc-4.3.3 and gcc-4.5.1

Is this expected behavior? How are we supposed to work around the 'dependent name' law for accessing parent template class' member typedefs?

like image 956
xtofl Avatar asked Nov 15 '12 20:11

xtofl


1 Answers

You probably want to do:

using MemberType = typename TBase<T>::MemberType; // new type alias syntax

or

typedef typename TBase<T>::MemberType MemberType; // old type alias syntax

The syntax using Base::member; can only be used to bring the declarations of non-type members into scope.


Also note that none of these are actually required, you can qualify each use (for types with the base, for non-types with either this-> or the base) and that will make the symbol dependent.

like image 123
David Rodríguez - dribeas Avatar answered Sep 18 '22 12:09

David Rodríguez - dribeas