Michael Francis
Michael Francis

Reputation: 8737

Template weirdness

I have five classes, declared so:

template <typename T>
class A {
    void fn(X);
};
template <typename T>
class B {};
class C {};
class D {};
class X {};

and I have two instances declared so:

A<B<C>> abc;
A<B<D>> abd;

How can I templatize fn so that one must call abc.fn() with an object of type C and abd.fn() with an object of type D?

Upvotes: 1

Views: 77

Answers (2)

Vaughn Cato
Vaughn Cato

Reputation: 64298

You can do a partial specialization of your class like this:

template <typename T> class A;
template <typename T> class B {};

template <typename T>
class A<B<T> > {
  public:
    void fn(T) { }
};

class C {};

class D {};

int main(int,char**)
{
  A<B<C>> abc;
  A<B<D>> abd;
  abc.fn(C());
  abd.fn(D());
  return 0;
}

If you want it to work for any template, and not just B, you can partially specialize class A like this:

template <typename T,template <typename> class U>
class A<U<T> > {
  public:
    void fn(T) { }
};

Upvotes: 3

Karthik T
Karthik T

Reputation: 31952

This is not going to be too pretty.

template <typename T>
class B {public: typedef T type;};

template <typename T>
class A {
    void fn(typename T::type X);
    //void fn(...){}  // would prevent an error if T does not have type.
};

Basically you save the type in a typedef and then use that in A. This would error out of course if B does the T of A does not have T::type.

Upvotes: 2

Related Questions