В случае использования статического полиморфизма, особенно в шаблонах (например, с шаблоном политики/стратегии), может потребоваться вызвать базовый элемент функции, но вы не знаете, был ли экземпляр класса фактически полученным из этой базы или нет.
Это легко может быть решена с помощью старого хорошего эллиптического трюка С++:
#include <iostream>
template <class I>
struct if_derived_from
{
template <void (I::*f)()>
static void call(I& x) { (x.*f)(); }
static void call(...) { }
};
struct A { void reset() { std::cout << "reset A" << std::endl; } };
struct B { void reset() { std::cout << "reset B" << std::endl; } };
struct C { void reset() { std::cout << "reset C" << std::endl; } };
struct E: C { void reset() { std::cout << "reset E" << std::endl; } };
struct D: E {};
struct X: A, D {};
int main()
{
X x;
if_derived_from<A>::call<&A::reset>(x);
if_derived_from<B>::call<&B::reset>(x);
if_derived_from<C>::call<&C::reset>(x);
if_derived_from<E>::call<&E::reset>(x);
return 0;
}
Возникает вопрос:
- Есть ли более простой способ (например, SFINAE не выглядит так), чтобы достичь такого же результата в С++ 11/С++ 14?
- Будет ли пустой вызов функции параметра эллипсиса отменен оптимизацией компилятора? Надеюсь, что такой случай не является особенным против какой-либо "нормальной" функции.