我希望能够创建非模板函数,该函数需要从少数其他类继承类的类。
这样的事情
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)将此功能作为调用“符合协议”的语言的一部分
如果您放松(消除)非模板性的要求,则通过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);
}
(为简洁起见,我将基数限制为两个 - 你实际上可以将这个多视图适配器扩展到任意一个包 - 并且暂时从临时构建 - 仍然不是火箭科学。)
定义一个新的接口I
,它源自A1
和A3
(但不实现任何纯虚函数),并使Foo
取const I&
。从I
派生的类必须覆盖A1
和A3
中的纯虚拟。