views:

184

answers:

2

Two-phase lookup question: Is there a more synthetic way to write this code, i.e. avoiding all those using directives? Something like using CBase<T>; is what I would like, but it is not accepted.

#include <iostream>

template <typename T>
class CBase
{
protected:
    int a, b, c, d;   // many more...

public:
    CBase() {
        a = 123; c = 0;
    }
};


template <typename T>
class CDer : public CBase<T>
{
//  using CBase<T>;     // error, but this is what I would like
    using CBase<T>::a;
    using CBase<T>::b;
    //...

public:
    CDer() {
        std::cout << a << this->c;
    }
};


int main()
{
    CDer<int> cd;
}

In my real code there are many more member variables/functions, and I was wondering if it is possible to write shorter code in some way.
Of course, using the this->c syntax does not solve the problem...

Thank's!


gcc 4.1 MacOS X 10.6

+2  A: 

I reduced the testcase and then consider three options

template<typename T> struct Base { int a; };

Option 1

template<typename T> struct Der : Base<T> {
  void f() { 
    int &ra = Der::a;
    // now use ra
  }
}

Option 2

template<typename T> struct Der : Base<T> {
  void f() { 
    // use this->a instead
    // or Der::a
  }
}

Option 3

// use your using declarations
Johannes Schaub - litb
Well, instead of: int I would use a using directive. It is shorter and more explicit. I am starting to think there is no way to do it. I would have liked if this syntax would have been accepted: using CBase<T>;
Pietro
@Pietro, since the compiler has no clue what names are made visible, it would render the whole rationale of not looking into the base for unqualified names for naught. The idea is that a simple `a` has no apparent relation to the `T` template parameter. And making it have a different meaning depending on what variables the base defines (even a private variable will change its meaning and make the access ill-formed!) isn't any good. Notice that the base class can be specialized for a given `T`. You have to explicitly declare that you *want* to depend on meanings that the base class defines.
Johannes Schaub - litb
@Johannes: you mean I had better surrender? After all it is just a stylistic detail. I think I won't kill myself for that.
Pietro
A: 

It doesn't look like most of those variables are parameterized. Does CBase use them all, or just a? If not, move them into a new non-template base of CDer.

Or, pack them all into a POD struct and then using CBase<T>::m_ints;.

High overhead solution: non-templated virtual base.

Not sure but worth a try: nest the definition of CDer inside CBase and then typedef it into namespace scope.

Potatoswatter
Yes, the variables in the real code are parametrized, and CBase would use them all. Moving the variables in a non template base class would solve the problem for CBase, but not for CDer. The POD still forces me to add a using directive for every variable. The virtual overhead is not affordable.
Pietro