带有重载成员函数的C++ std :: mem_fn

Fra*_*Liu 8 c++ function-pointers c++11

编译以下代码时,Visual Studio报告:

\main.cpp(21): error C2664: 'std::_Call_wrapper<std::_Callable_pmd<int ClassA::* const ,_Arg0,false>,false> std::mem_fn<void,ClassA>(int ClassA::* const )' : cannot convert argument 1 from 'overloaded-function' to 'int ClassA::* const '
    1>          with
    1>          [
    1>              _Arg0=ClassA
    1>          ]
    1>          Context does not allow for disambiguation of overloaded function
Run Code Online (Sandbox Code Playgroud)

编译时为什么编译器会混淆mem_fptr1?但是mem_fptr2当我指定类型时,有些可以.

我可以创建成员函数指针指向不带参数的重载成员函数吗?

class ClassA
{
public:
    void memberfunction()
    {
        std::cout <<"Invoking ClassA::memberfunction without argument" << std::endl;
    }

    void memberfunction(int arg)
    {
        std::cout << "Invoking ClassA::memberfunction with integer " << arg << std::endl;
    }
};

int main()
{
    auto mem_fptr1 = std::mem_fn<void, ClassA>(&ClassA::memberfunction);
    auto mem_fptr2 = std::mem_fn<void, ClassA, int>(&ClassA::memberfunction);

    mem_fptr1(ClassA());
    mem_fptr2(ClassA(), 3);
}
Run Code Online (Sandbox Code Playgroud)

eca*_*mur 15

采用可变参数类型列表模板重载在C++ 11中引入,但在C++ 14中作为缺陷#2048删除.指定特定重载的方法是将函数类型指定为第一个模板参数(第二个模板参数,类类型,可以省略,因为它可以推导出来):

auto mem_fptr1 = std::mem_fn<void()>(&ClassA::memberfunction);
auto mem_fptr2 = std::mem_fn<void(int)>(&ClassA::memberfunction);
Run Code Online (Sandbox Code Playgroud)

功能类型R然后与类型组成TR T::*,得到的成员函数类型.这也允许形成std::mem_fn数据成员(其中R是非功能类型).

请注意,您的代码(for mem_fptr2)在C++ 14中不起作用,其中模板重载会删除参数类型的可变参数列表; 上述代码适用于标准的两个版本.

另一种方法是执行成员函数转换; 在这种情况下,您不需要指定模板参数mem_fn:

auto mem_fptr1 = std::mem_fn(
    static_cast<void (ClassA::*)()>(&ClassA::memberfunction));
auto mem_fptr2 = std::mem_fn(
    static_cast<void (ClassA::*)(int)>(&ClassA::memberfunction));
Run Code Online (Sandbox Code Playgroud)