C++派生类重载函数(带有 std::function 参数)不可见
C++ derived class overloaded function (with std::function argument) not visible
让我用下面的例子来说明我的问题。假设我们有一个基类,它定义了方法Exec,该方法接受任何类型的一个参数(模板(。该方法 Exec调用已重载的方法Call,以将具有不同参数的 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)>&)'
我的问题是:为什么编译器在派生类(void Derived::Exec( std::function<void(int)> func )
(中看不到Exec
的定义? 我希望在重载解决期间选择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
传递给接受可转换为std::function<void(void)>
的东西的Base::Call
,而 lambda 不是。 由于静态调度,Derived::Call
从未被选中,这就是错误的原因。
- 为什么 std::function 可以作为 std::not2 的参数?
- 传递给std::function template的template参数究竟代表什么
- 如果模板没有可变参数,则 Lambda 被推导出为 std::function
- 可变参数模板参数扩展 类型为 std::function 的类成员
- std::function<void()> 接受参数
- 在标准中,模板参数的语法在哪里定义,例如,'std::function<int(char)>'?
- C++派生类重载函数(带有 std::function 参数)不可见
- C++ 事件管理器的回调,使用 std::function 和 std:bind 以及派生类作为参数
- 将函数的参数 - 签名从使用 'std::function<T>' 转换为模板参数类型
- C++初始化 std::function 时如何将占位符绑定到引用/引用参数?
- 仅当一个参数中未使用 std::function 时,模板函数替换才有效
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 将另一个类的成员函数传递到 std::function 参数中
- 如何返回用参数包定义的成员函数的std::function对象
- 了解 std::function 的晦涩模板参数
- 将 std::function* 传递给模板参数
- 构造函数模板参数推导,其中 std::function 作为参数
- 使用"std::function"和先前推断的模板参数替换失败 - 为什么?
- 使用 std::function 作为具有任意数量参数的数据成员
- 将可变参数函数参数转发到 std::function 对象