When compiling the following code, Visual Studio reports:
\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
Why is the compiler confused when creating mem_fptr1
? But some how mem_fptr2
is ok when I specify the types.
Can I create member function pointer to an overloaded member function that takes no argument?
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);
}
The template overloads taking a variadic list of argument types were introduced in C++11 but removed in C++14 as defect #2048. The way to specify a particular overload is to specify a function type as the first template argument (the second template argument, the class type, can be omitted as it can be deduced):
auto mem_fptr1 = std::mem_fn<void()>(&ClassA::memberfunction);
auto mem_fptr2 = std::mem_fn<void(int)>(&ClassA::memberfunction);
The function type R
is then composed with the class type T
as R T::*
to give the member function type. This also allows forming a std::mem_fn
to a data member (where R
is a non-function type).
Note that your code (for mem_fptr2
) does not work in C++14 where the template overloads taking a variadic list of argument types are removed; the above code will work in both versions of the Standard.
An alternative is to perform a member function cast; in this case you do not need to specify template arguments to 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));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With