简体   繁体   English

C ++派生类重载函数(带有std :: function参数)不可见

[英]C++ derived class overloaded function (with std::function argument) not visible

Let me illustrate my question with following example. 让我用下面的例子说明我的问题。 Suppose we have a base class that defines method Exec that takes one argument of any type (template). 假设我们有一个基类,它定义了一个方法Exec ,它接受任何类型(模板)的一个参数。 The method Exec calls then method Call that has been overloaded to take as an argument an std::function object with different parameters. 方法Exec调用then方法调用已经重载的方法,将带有不同参数的std :: function对象作为参数。

Now suppose we have a derived class that inherits after Base and overloads Exec so it takes as an argument yet another std::function object (with different argument set). 现在假设我们有一个派生类,它在Base之后继承并重载Exec,因此它将另一个std :: function对象(具有不同的参数集)作为参数。

Something like: 就像是:

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 );
  }
};

Now suppose we want to call: 现在假设我们要打电话:

Derived::Exec( []( int i ){std::cout << i << std::endl;} );

this will give following compilation error (I tried with g++ 4.8.5 and 8.1.1): 这将产生以下编译错误(我尝试使用g ++ 4.8.5和8.1.1):

 error: no matching function for call to 'Base::Call(main(int, char**)::<lambda(int)>&)' 

My question is: why does the compiler not see the definition of Exec in Derived class ( void Derived::Exec( std::function<void(int)> func ) )? 我的问题是:为什么编译器在Derived类中看不到Exec的定义( void Derived::Exec( std::function<void(int)> func ) )? I would expect that during overload resolution the Derived::Exec will be chosen as it is most appropriate for the given argument: 我希望在重载解析期间选择Derived::Exec因为它最适合给定的参数:

 []( int i ){std::cout << i << std::endl;}

What am I missing? 我错过了什么?

Lambda expressions produce closures that have anonymous and unique types. Lambda表达式生成具有匿名唯一类型的闭包 These types are completely unrelated from std::function . 这些类型与std::function完全无关。

Your template is a better match as it can deduce the exact type of the closure . 您的template是一个更好的匹配,因为它可以推断出闭包的确切类型。 Invoking the non- template overload would require an std::function instance to be created from the closure (not an exact match). 调用非template重载将需要从闭包创建std::function实例(不是精确匹配)。

The lambda []( int i ){std::cout << i << std::endl;} is convertible to std::function<void(int)> not to std::function<void(void)> . lambda []( int i ){std::cout << i << std::endl;}可转换为std::function<void(int)>而不是std::function<void(void)>

Even when the template function in Base is being selected because of perfect match, inside of it you're passing func to Base::Call that accept something convertible to std::function<void(void)> , and the lambda is not. 即使在Base中的模板函数由于完美匹配而被选中时,你也可以将func传递给Base::Call ,它接受可转换为std::function<void(void)> ,而lambda则不然。 Derived::Call is never selected because of static dispatch, that's the reason of the error. Derived::Call由于静态调度而从未选择Derived::Call ,这就是错误的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 派生类中的重载函数 (C++) - Overloaded function in derived class (C++) 具有多态性的派生类中的重载函数(C++) - Overloaded function in derived class with Polymorphism (C++) C ++重载函数,一个接受基类的参数,另一个接受派生类的参数 - C++ Overloaded function, one takes takes argument of base class, another takes argument of derived class 从基对象上的 C++ 类调用重载的派生函数不会调用重载函数 - Call overloaded, derived function from C++ class on base object does not call the overloaded function 如何从派生类中调用在派生类中重载的模板类函数? - c++ How do you call a template class function that is overloaded in the derived class, from the derived class? 带有 std::is_base_of 的派生类的 C++ 模板函数 - C++ template function for derived class with std::is_base_of 来自派生类的C ++ std :: function绑定 - C++ std::function bind from derived class C ++重载函数作为模板参数 - C++ overloaded function as template argument 访问 C++ 中派生的 class 的模板参数的虚拟成员 function - Accessing a virtual member function of a template argument derived class in C++ 当在C ++中获得指向基类的指针时,为什么不为派生类对象调用重载函数? - Why is not overloaded function for derived class object invoked when given a pointer to base class in C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM