Вы можете добавить простую перегрузку пересылки и использовать SFINAE, чтобы условно отключить ее, когда элемент не существует в базовом классе. Как это:
template<typename V = T, typename = decltype(&foo<Enable, V>::say_hello)>
void say_hello()
{
bar::foo::say_hello();
}
Посмотреть вживую
Нам нужно использовать &foo<Enable, V>::say_hello
вместо &foo<Enable, T>::say_hello
, чтобы отложить проверку и заставить ее произойти во время подстановки (когда делается попытка вызвать функцию), в отличие от того, что происходит при создании экземпляра bar
.
Если элемент не существует, разрешение перегрузки отменяет новую перегрузку (из-за неправильно сформированной замены), как будто ее никогда не существовало.
Но стоит отметить, что это не будет работать для наборов перегрузки (потому что нельзя взять указатель на член набора перегрузки). Он будет работать только в том случае, если вы знаете, что существует только одна перегрузка, в которой указатель на член может быть сформирован однозначно.