Недавно я столкнулся с проблемой при использовании схемы частного наследования, в которой базовый класс определил метод шаблона, а (частный) производный класс сделал этот метод общедоступным через объявление using в спецификаторе доступа public
.Шаблон был разработан для получения адреса функции и вызова указателя на эту функцию.Однако при попытке передать имя функции в метод шаблона производного класса я получаю сообщение об ошибке, в котором говорится, что метод базового класса не может получить доступ к закрытому члену, объявленному в производном классе.Вот фрагмент кода, который моделирует проблему:
class A
{
public:
template<class T> void Funct(T pFunct) { }
};
class B : private A
{
public:
using A::Funct;
};
void Show(void) { }
int main(void)
{
B b;
b.Funct(Show);
}
Точное сообщение об ошибке: 'A::Funct' : cannot access private member declared in class 'B'
Я могу решить проблему просто:
1) Перед именем аргумента функции указывается оператор address-of:
b.Funct(&Show);
2) Явно определяющий аргумент типа шаблона:
b.Funct<void(*)(void)>(Show)
Если бы функция Show()
былаКроме того, мне нужно было бы явно квалифицировать шаблон, используя правильные аргументы типа шаблона, используемые для создания экземпляра Show
.
Мой вопрос не в том, как решить проблему, а в том, почему генерируется сообщение об ошибке.Почему создание экземпляра Funct()
с Show
по сравнению с &Show
приводит к тому, что компилятор делает две разные вещи.И почему создание экземпляра Funct()
с помощью Show
приводит к тому, что метод Funct()
пытается получить доступ к закрытым данным в классе B
(который, я предполагаю, является подобъектом A
в классе B
)?