C ++:参数类型需要从一些类似于接口的类中继承

时间:2018-08-31 20:47:31

标签: c++ c++11 templates inheritance multiple-inheritance

我希望能够创建非模板函数,该函数要求从其他几个类继承类的类型。

类似的东西

class A1
{};

class A2
{};

class A3
{};

class B: public A1, public A2, public A3
{};

class C: public A1, public A3
{};

void Foo(const C&)
{}

int main(void)
{
    B b;
    C c;

    Foo(b); // error. But B inherited from A1 and A3, so I want to be able pass it
    Foo(c); // ok

    return 0;
}

我很高兴听到任何解决此问题的建议。

注意:某些语言(如Swift和Objective-C)将此功能作为称为“符合协议”的语言的一部分

2 个答案:

答案 0 :(得分:2)

如果您放宽(消除)非模板性的要求,则可以通过SFINAE完成,例如:

template<class T>
typename std::enable_if<
        std::is_base_of<A1, T>::value
        && std::is_base_of<A3, T>::value>::type
    Foo(T const &);

否则,您将需要更多技巧,更具体地说,尽管模板应该与其他地方隔离,但仍然需要模板化解决方案。简要概述的一种可能的解决方案是:

struct A1 {};
struct A2 {};

struct B: A1, A2 {};
struct C: A1, A2 {};

template<class B1, class B2> struct product {
    template<class T> product(T &t): b1(t), b2(t) {}
    operator B1 &() const { return b1; }
    operator B2 &() const { return b2; }
private:
    B1 &b1;
    B2 &b2;
};

void f(product<A1, A2> p) {}

int main() {
    B b;
    C c;
    f(b);
    f(c);
}

(为简便起见,我将基本数量限制为两个,您实际上可以将多视图适配器扩展到任意包,并保留临时对象的构造,但仍然不是火箭科学。)

答案 1 :(得分:1)

定义一个从IA1派生而来的新接口A3(但不实现其任何纯虚函数),并使Foo取{ {1}}。从const I&派生的类将必须覆盖IA1中的纯虚函数。