Eduard Rostomyan
Eduard Rostomyan

Reputation: 6546

Template class specialization function call. C++

consider this code.

template<class T>
class A
{
    public:
      void f(){..}
      void h(){..}
};


template<>
class A<int>
{
    public:
      void f(){// something different..}
      //void h(){..}
};

int main()
{
    A<int> obj;
    obj.h(); // I want to call A<T>::h(), but compiler erred that there is no h function in A<int>
}

Is there a way to this call?? Or some workaround?

Upvotes: 2

Views: 77

Answers (3)

Benjamin Schulte
Benjamin Schulte

Reputation: 873

This code works for me:

template<class T>
class BaseA {
public:
  void f(){...}
  void h(){...}
};

template<class T>
class A : public BaseA<T>
{
};


template<>
class A<int> : public BaseA<int>
{
    public:
      void f(){...}
      //void h(){..}
};

int main()
{
    A<int> obj;
    obj.h(); // I want to call A<T>::h(), but compiler erred that there is no h function in A<int>
}

It declares a base class which is inherited by both.

Upvotes: 2

Barry
Barry

Reputation: 303007

A<T> is a class template that introduces a family of classes A based on any typename T. A<int> is an explicit specialization of A<T> - it supersedes the generic class definition. It's no different from having written:

class Aint {
public:
    void f(); 
};

This specialization only has a single member function - f. So when you try to do this:

A<int> obj;
obj.h();

That doesn't compile because A<int> does not have a member function named h. Despite both being named A, A<int> and A<T> are unrelated - one is not a base class of the other, and it doesn't matter what functions and members exist in the general A<T> - the A<int> specialization doesn't have them.

If h is something common, you could move it into a base class:

struct ABase { // or alternatively ABase<T>
    void h();
}

template <typename T>
class A : ABase {
    void f();
};


template <>
class A<int> : ABase {
    void f();
};

That way all of the instantiations of A would have an h(). That is, until somebody goes ahead and adds:

template <>
class A<char> // no inheritance
{
    // no h()
};

Upvotes: 3

TartanLlama
TartanLlama

Reputation: 65620

Depending on how much stuff you are changing in your specialization, you might be better off just specializing f for A<int> rather than specializing the entire class:

template<class T>
class A
{
    public:
      void f(){cout << "standard";}
      void h(){cout << "standard";}
};

template<>
void A<int>::f() {cout << "specialized";}

int main()
{
    A<bool>{}.f(); //outputs standard
    A<int> obj;
    obj.f();       //outputs specialized
    obj.h();       //outputs standard
}

If your specialization is more complex than that, you could factor the common behaviour out into a base class and derive A from that.

Upvotes: 2

Related Questions