[英]C++ derived class overloaded function (with std::function argument) not visible
讓我用下面的例子說明我的問題。 假設我們有一個基類,它定義了一個方法Exec ,它接受任何類型(模板)的一個參數。 方法Exec調用then方法調用已經重載的方法,將帶有不同參數的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)>&)'
我的問題是:為什么編譯器在Derived類中看不到Exec
的定義( void Derived::Exec( std::function<void(int)> func )
)? 我希望在重載解析期間選擇Derived::Exec
因為它最適合給定的參數:
[]( int i ){std::cout << i << std::endl;}
我錯過了什么?
Lambda表達式生成具有匿名和唯一類型的閉包 。 這些類型與std::function
完全無關。
您的template
是一個更好的匹配,因為它可以推斷出閉包的確切類型。 調用非template
重載將需要從閉包創建std::function
實例(不是精確匹配)。
lambda []( int i ){std::cout << i << std::endl;}
可轉換為std::function<void(int)>
而不是std::function<void(void)>
。
即使在Base中的模板函數由於完美匹配而被選中時,你也可以將func
傳遞給Base::Call
,它接受可轉換為std::function<void(void)>
,而lambda則不然。 Derived::Call
由於靜態調度而從未選擇Derived::Call
,這就是錯誤的原因。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.