我有一个使用模板的给定C ++代码,并声明了一个以类C<T1, B1<T2> >为模板参数的类B1。现在,我希望C<T1, B2<T2> >B1完全相同,除了一些我明确为B2重新声明的功能。下面是一个从B2继承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;
}


我想更改getVal()的实现而不必重新声明doSomething()C<T1, B2<T2> >。不幸的是,这不起作用(错误:变量C<int, B2<int> > c2具有初始化程序,但类型不完整)。

是否有任何优雅的方法无需重新声明C及其所有功能?

P.S .:根据注释固定main()中声明的函数。

最佳答案

C ++模板专业化基于模式匹配。它不使用继承。

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


仅匹配B1,就上述而言,B2是不相关的类型。您的错误发生在doSomething代码之前很久了,现在它是一个红色鲱鱼。

首先要做的是修复以上代码段:

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


现在它的模式同时匹配B1B2。接下来对doSomething做同样的事情:

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


和代码应该工作。

如果需要,可以通过SFINAE进行进一步限制。

10-07 16:34
查看更多