Позвольте мне проиллюстрировать мой вопрос следующим примером.Предположим, у нас есть базовый класс, который определяет метод Exec , который принимает один аргумент любого типа (шаблона).Метод Exec вызывает затем метод Вызов , который был перегружен для получения в качестве аргумента объекта std :: function с другими параметрами.
Теперь предположим, что у нас есть производнаякласс, который наследуется после Base и перегружает Exec , поэтому он принимает в качестве аргумента еще один объект std :: function (с другим набором аргументов).
Что-то вроде:
struct Base
{
template<typename Func>
static void Exec( Func func )
{
Call( func );
}
static void Call( std::function<void(void)> func )
{
func();
}
/*other definitions of Call for other std::functions*/
};
struct Derived : public Base
{
using Base::Exec;
static void Exec( std::function<void(int)> func )
{
func( 10 );
}
};
Теперь предположим, что мы хотим вызвать:
Derived::Exec( []( int i ){std::cout << i << std::endl;} );
Это даст следующую ошибку компиляции (я пробовал с g ++ 4.8.5 и 8.1.1):
error: no matching function for call to 'Base::Call(main(int, char**)::<lambda(int)>&)'
Мой вопрос: почему компилятор не видит определения Exec
в классе Derived (void Derived::Exec( std::function<void(int)> func )
)?Я ожидаю, что при разрешении перегрузки будет выбран Derived::Exec
, так как он наиболее подходит для данного аргумента:
[]( int i ){std::cout << i << std::endl;}
Чего мне не хватает?