为什么重载函数的函数指针需要static_cast?
Why function pointer of overloaded function need static_cast?
对于下面的代码,我得到了错误
#include <iostream>
#include <functional>
using namespace std;
class A {};
class B {};
namespace N
{
void func(A a, int z){}
void func(B a, int z){}
}
void func_1(std::function<void(A, int)> x)
{
A a;
x(a, 1);
}
int main()
{
func_1(N::func);
return 0;
}
错误:
main.cpp:23:19: error: cannot resolve overloaded function 'func' based on conversion to type 'std::function<void(A, int)>'
23 | func_1(N::func);
如果我们将 func_1(N::func);
静态转换为 func_1(static_cast<void (&)(A, int)>(N::func));
,那么这个工作正常。但我希望它能在没有演员表的情况下工作。
std::function<void(A, int)>
比 void(*)(A, int)
.
更复杂
template< class F >
function( F f );
Initializes the target with std::move(f)
. If f
is a null pointer to function or null pointer to member, *this
will be empty after the call. This constructor does not participate in overload resolution unless f
is Callable for argument types Args...
and return type R
.
您甚至不知道哪些构造函数参与了重载决议,直到您决定 N::func
您的意思。
人们可以设想一种组合的重载决议和模板参数推导方案,该方案可以通过在(任意多个)构造函数的其他有效实例中尝试 std::function<void(A, int)>::function<void(*)(A, int)>
来“在中间相遇”。
问题比比皆是。
- 它必须得到可证明的答案。通常有无限可能的模板实例化。如果你通过了
int g(A, int)
. ,你还希望它能够选择 int(*)(A, int)
- 它确实应该同意当前的方案,得出明确的答案。
- 每个编译器供应商都必须正确实施它。
作为一种方便的解决方法,您可以提供这种 func_1
重载。
...
void func_1(void(*x)(A, int))
{
func_1(std::function<void(A, int)>{x});
}
现在它可以在没有 static_cast
的情况下正常工作:demo
对于下面的代码,我得到了错误
#include <iostream>
#include <functional>
using namespace std;
class A {};
class B {};
namespace N
{
void func(A a, int z){}
void func(B a, int z){}
}
void func_1(std::function<void(A, int)> x)
{
A a;
x(a, 1);
}
int main()
{
func_1(N::func);
return 0;
}
错误:
main.cpp:23:19: error: cannot resolve overloaded function 'func' based on conversion to type 'std::function<void(A, int)>'
23 | func_1(N::func);
如果我们将 func_1(N::func);
静态转换为 func_1(static_cast<void (&)(A, int)>(N::func));
,那么这个工作正常。但我希望它能在没有演员表的情况下工作。
std::function<void(A, int)>
比 void(*)(A, int)
.
template< class F > function( F f );
Initializes the target with
std::move(f)
. Iff
is a null pointer to function or null pointer to member,*this
will be empty after the call. This constructor does not participate in overload resolution unlessf
is Callable for argument typesArgs...
and return typeR
.
您甚至不知道哪些构造函数参与了重载决议,直到您决定 N::func
您的意思。
人们可以设想一种组合的重载决议和模板参数推导方案,该方案可以通过在(任意多个)构造函数的其他有效实例中尝试 std::function<void(A, int)>::function<void(*)(A, int)>
来“在中间相遇”。
问题比比皆是。
- 它必须得到可证明的答案。通常有无限可能的模板实例化。如果你通过了
int g(A, int)
. ,你还希望它能够选择 - 它确实应该同意当前的方案,得出明确的答案。
- 每个编译器供应商都必须正确实施它。
int(*)(A, int)
作为一种方便的解决方法,您可以提供这种 func_1
重载。
...
void func_1(void(*x)(A, int))
{
func_1(std::function<void(A, int)>{x});
}
现在它可以在没有 static_cast
的情况下正常工作:demo