Я не уверен, что понимаю, о чем вы спрашиваете, но, похоже, вам не хватает необходимого набора CRTP:
template<class T>
struct A {
void func() {
T& self = *static_cast<T*>(this); // CRTP cast
self.func();
}
};
struct V : A<V> { // B for the case of virtual func
virtual void func() {
std::cout << "V::func\n";
}
};
struct NV : A<NV> { // B for the case of non-virtual func
void func() {
std::cout << "NV::func\n";
}
};
Если T не объявляет свой собственный func, это будет бесконечная рекурсия, поскольку self.func найдет A :: func. Это верно, даже если производный класс T (например, DV ниже) объявляет свой собственный функционал, но T этого не делает.
Тест с другим окончательным переопределением, чтобы показать отправку работ в соответствии с объявлением:
struct DV : V {
virtual void func() {
std::cout << "DV::func\n";
}
};
struct DNV : NV {
void func() {
std::cout << "DNV::func\n";
}
};
template<class B>
void call(A<B>& a) {
a.func(); // always calls A<T>::func
}
int main() {
DV dv;
call(dv); // uses virtual dispatch, finds DV::func
DNV dnv;
call(dnv); // no virtual dispatch, finds NV::func
return 0;
}