我希望能够创建非模板函数,该函数要求从其他几个类继承类的类型。
类似的东西
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)将此功能作为称为“符合协议”的语言的一部分
答案 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)
定义一个从I
和A1
派生而来的新接口A3
(但不实现其任何纯虚函数),并使Foo
取{ {1}}。从const I&
派生的类将必须覆盖I
和A1
中的纯虚函数。