簡體   English   中英

C ++派生類重載函數(帶有std :: function參數)不可見

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM