user4523816
user4523816

Reputation:

C++ subclassing in template parameters

I have a given C++ code using templates and declaring a class C<T1, B1<T2> > with a class B1 as template argument. I now want C<T1, B2<T2> > to do exactly the same as for B1 except some functions that I redeclare explicitly for B2. Below is a small example by inheriting B2 from B1.

template <typename T1>
class B1 {};

template <typename T1>
class B2: public B1<T1> {};

template <typename T1, typename T2>
class C;

template <typename T1, typename T2>
class C<T1, B1<T2> >
{
public:
    C(int i) {
        // do sth.
    }
};

template <typename T1, typename T2>
int getVal(C<T1, B2<T2> >& b2) {
    return 2;
}

template <typename T1, typename T2>
int getVal(C<T1, B1<T2> >& b1) {
    return 1;
}

template <typename T1, typename T2>
int doSomething(C<T1, B1<T2> >& c) {
    return getVal(c);
}

int main()
{
    C<int, B1<int> > c1(1);
    C<int, B2<int> > c2(1);
    cout << doSomething(c1); // output 1
    cout << doSomething(c2); // output 2
    return 0;
}

I want to change the implementation of getVal() without having to redeclare doSomething() and C<T1, B2<T2> >. Unfortunately this does not work (error: variable C<int, B2<int> > c2 has initializer but incomplete type).

Is there any elegant way without having to redeclare C and all of its functions?

P.S.: fixed declared functions in main() according to comment.

Upvotes: 0

Views: 386

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275340

C++ template specialization is based off pattern matching. It does not use inheritance.

template <typename T1, typename T2> class C<T1, B1<T2> >

only matches B1, As far as the above is concerned, B2 is an unrelated type. Your error happened long before the doSomething code, it is a red herring for now.

The first thing to do is fix the above snippet:

template <class T1, template<class>class B, class T2>
class C<T1, B<T2> >

now it pattern matches both B1 and B2. Next do the same to doSomething:

template <class T1, template<class>class B, class T2>
int doSomething(C<T1, B<T2> >& c)

and the code should work.

Further restriction can be done via SFINAE if needed.

Upvotes: 1

Related Questions