c++ - 具有重载成员函数的C++ std::mem_fn

标签 c++ c++11 function-pointers

编译以下代码时,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

为什么创建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);
}

最佳答案

template overloads taking a variadic list of argument types在C++ 11中引入,但在C++ 14中作为defect #2048删除。指定特定重载的方法是将函数类型指定为第一个模板参数(第二个模板参数,即类类型,可以省略,因为可以推导出):

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

然后,将函数类型R与类类型T组合为R T::*组成成员函数类型。这还允许将std::mem_fn形成为数据成员(其中R是非函数类型)。

注意,您的代码(对于mem_fptr2)在C++ 14中不起作用,在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));

关于c++ - 具有重载成员函数的C++ std::mem_fn,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45841427/

相关文章:

c++ - 为什么指定的初始化程序没有在 g++ 中实现

c++ - 根据标准,这个 constexpr offset_of 的定义是否正确?

c++ - 指向虚函数的指针是否仍会被虚拟调用?

c++ - ISO C++ 禁止在指向函数的指针和指向对象的指针之间进行转换

c++ - #include <limits> 是跨平台的吗?

c++ - 私有(private)插槽 Qt 上的声明不一致

c++ - 在 Boost.Log 中重载插入运算符(Boost 1.60.0)

c++ - 如何检查套接字是否已连接

在c中运行时调用函数

c++ - 为什么如果我注释了 "while" block ,程序就会死锁?其中的 "yield"行有何作用?