Как сказал Магнус Ског, часть шаблона на самом деле не актуальна. То, что это сводится к тому, что:
(ptr->* &Base::sayHi)()
вроде бы работает, но
ptr->Base::sayHi()
, очевидно, не потому, что sayHi чисто виртуальный.
Мне не удалось найти в стандарте ничего о том, что происходит, когда вы берете адрес виртуальной или чисто виртуальной функции. Я не уверен, что это законно. Однако он работает в GCC и MSVC, и онлайн-компилятор Comeau тоже не жалуется.
Редактировать
Даже если оно действительно, как говорят ваши правки, мне все еще интересно, что это значит.
Если для простоты предположить, что sayHi
не является чистым (поэтому существует определение Base::sayHi
), то что произойдет, если я возьму его адрес? Получу ли я адрес Base :: sayHi или адрес функции, на которую указывает vtable (в данном случае Derived :: sayHi)?
Видимо, компиляторы предполагают последнее, но почему?
Вызов ptr->Base::sayHi()
вызывает sayHi
в базовом классе, но взятие адреса Base::sayHi
дает мне адрес Derived::sayHi
Мне это кажется противоречивым. Есть ли какое-то объяснение этому, которого я пропускаю?