Дело в том, что тип m1 void(S1::*)(void)
, а не void(S2::*)(void)
.Так что исправьте это, используя известное имя базового класса:
struct S1 {
void m1() {}
};
template<typename B> struct S2 : B {
void m2() {}
void m3();
};
template<typename S, typename B, void (B::*m)(void)> void f1(S* o) {
(o->*m)();
}
template<typename B> void S2<B>::m3() {
f1<S2, B, &B::m1>(this);
}
int main() {
S2<S1> o;
o.m3();
}
Конечно, это (пока) не масштабируется до методов, определенных в косвенных базовых классах, но с небольшим количеством TMP это можно сделать (будет)посмотрим, смогу ли я опубликовать это, пока длится перерыв Going Native 2012:))
Более «гибкий» подход будет выглядеть так:S2<B>&
можно преобразовать в B&
, если макет класса уже явно не гарантирует этого, как в вашем текущем примере.