简体   繁体   English

为什么重载函数的函数指针需要static_cast?

[英]Why function pointer of overloaded function need static_cast?

For the below code, I get the error对于下面的代码,我收到错误

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

Error:错误:

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

If we do the static cast for the func_1(N::func);如果我们对func_1(N::func);进行静态func_1(N::func); as func_1(static_cast<void (&)(A, int)>(N::func));作为func_1(static_cast<void (&)(A, int)>(N::func)); , then this work fine. ,那么这个工作正常。 But I would expect this to work without a cast.但我希望这在没有演员的情况下工作。

std::function<void(A, int)> is more complicated than void(*)(A, int) . std::function<void(A, int)>void(*)(A, int)更复杂。

 template< class F > function( F f );

Initializes the target with std::move(f) .std::move(f)初始化目标。 If f is a null pointer to function or null pointer to member, *this will be empty after the call.如果f是指向函数的空指针或指向成员的空指针,则调用后*this将为空。 This constructor does not participate in overload resolution unless f is Callable for argument types Args... and return type R .除非f对于参数类型Args...和返回类型R可调用的,否则此构造函数不参与重载决议。

You don't even know what constructors participate in overload resolution until you decide which N::func you mean.在您决定哪个N::func之前,您甚至不知道哪些构造函数参与了重载决议。

One can conceive of an combined overload resolution and template argument deduction scheme that could "meet in the middle" by trying std::function<void(A, int)>::function<void(*)(A, int)> among (arbitrarily many) other valid instantiations of the constructor.通过尝试std::function<void(A, int)>::function<void(*)(A, int)> (任意多个)构造函数的其他有效实例。

Problems abound with that.问题比比皆是。

  1. It has to provably arrive at an answer.它必须得到可证明的答案。 In general there are infinite possible instantiations of the templates.一般来说,模板有无限可能的实例化。 You'd also want it to be able to pick int(*)(A, int) if you passed it int g(A, int) .如果您将它传递给int g(A, int)您还希望它能够选择int(*)(A, int) int g(A, int)
  2. It really should agree with the current scheme where that arrives at an unambiguous answer.它确实应该同意当前的方案,得出明确的答案。
  3. Each of the compiler vendors have to implement it correctly.每个编译器供应商都必须正确实现它。

As a handy workaround you can provide this kind of func_1 overload.作为一种方便的解决方法,您可以提供这种func_1重载。

...

void func_1(void(*x)(A, int))
{
    func_1(std::function<void(A, int)>{x});
}

Now it works as desired without static_cast : demo现在它可以在没有static_cast情况下正常工作:演示

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM