我已经用模板化可变参数列表定义了接口,以具有与每种类型匹配的多种方法:
template <typename T> struct IfaceElement { virtual void m(const T &) = 0; };
template <typename... Ts> struct Iface : IfaceElement<Ts>... {};
我想要实现的是为不同数量的Event
对象提供一个接口。像这样:
struct A {};
struct B {};
struct Handler : Iface<A, B> {
void m(const A &) override { ... }
void m(const B &) override { ... }
}
它工作正常。
但是,我还想拥有一个实现该接口的类,它也是从可变参数模板中元生成的。
我认为这样的事情应该起作用:
template <typename T> struct IfaceElement { virtual void m(const T &) = 0; };
template <typename... Ts> struct Iface : IfaceElement<Ts>... {};
template <typename T> struct ImplElement : IfaceElement<T> {
void m(const T &) override {}
};
template <typename... Ts> struct Impl : Iface<Ts...>, ImplElement<Ts>... {};
struct Z {};
struct X {};
Impl<Z, X> q;
但是我遇到了编译器错误:
test.cpp:121:12: error: cannot declare variable 'q' to be of abstract type 'Impl<Z, X>'
121 | Impl<Z, X> q;
| ^
test.cpp:116:34: note: because the following virtual functions are pure within 'Impl<Z, X>':
116 | template <typename... Ts> struct Impl : Iface<Ts...>, ImplElement<Ts>... {};
| ^~~~
test.cpp:110:58: note: 'void IfaceElement<T>::m(const T&) [with T = X]'
110 | template <typename T> struct IfaceElement { virtual void m(const T &) = 0; };
| ^
test.cpp:110:58: note: 'void IfaceElement<T>::m(const T&) [with T = Z]'
似乎我从ImplElement
开始的实现与IfaceElement
纯方法不匹配。
任何想法我该如何解决?
答案 0 :(得分:0)
我已经弄清楚了,需要虚拟继承来匹配那些接口。
编译代码:
template <typename T> struct IfaceElement { virtual void m(const T &) = 0; };
template <typename... Ts> struct Iface : virtual IfaceElement<Ts>... {};
template <typename T> struct ImplElement : virtual IfaceElement<T> {
void m(const T &) override {}
};
template <typename... Ts> struct Impl : Iface<Ts...>, ImplElement<Ts>... {};
struct Z {};
struct X {};
Impl<Z, X> q;
答案 1 :(得分:0)
您是从IfaceElement
继承2次。一次通过ImplElement
,一次通过Iface
。
那是
template <typename... Ts> struct Impl : Iface<Ts...>, ImplElement<Ts>... {};
每个IfaceElement
将有两个相同的Ts
。
您可以使用虚拟继承对其进行修饰,但是为什么您需要从同一基础继承两次?
template <typename... Ts> struct Impl : ImplElement<Ts>... {};
每个IfaceElement
只会从Ts
继承一次。