C ++:需要从几个类似接口的类继承的参数类型

问题描述 投票:0回答:2

我希望能够创建非模板函数,该函数需要从少数其他类继承类的类。

这样的事情

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)将此功能作为调用“符合协议”的语言的一部分

c++ c++11 templates inheritance multiple-inheritance
2个回答
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
投票

定义一个新的接口I,它源自A1A3(但不实现任何纯虚函数),并使Fooconst I&。从I派生的类必须覆盖A1A3中的纯虚拟。

© www.soinside.com 2019 - 2024. All rights reserved.