Je suis tombé sur un cas d'utilisation où std::mem_fn
ne peut pas faire quelque chose qu'une fonction wrapper roulée à la main peut faire. Il apparaît lorsque la fonction enveloppe est utilisée sur quelque chose qui est pas de la classe de la méthode, mais un type implicitement convertible en elle:Déficience dans std :: mem_fn par rapport au foncteur roulé à la main
#include <functional>
struct A
{
};
struct B
{
B(A); // implicit conversion from A to B
void foo() const;
};
auto foo1 = std::mem_fn(&B::foo); // std::mem_fn
void foo2(const B& b) { b.foo(); } // hand-rolled wrapper
int main()
{
A a;
foo1(a); // doesn't work
foo2(a); // works fine
}
L'erreur du compilateur pour l'appel à foo1 est le suivant (avec GCC 4.8):
In file included from test.cpp:1:0:
functional: In instantiation of '_Res std::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)const>::_M_call(_Tp&, const volatile void*, _ArgTypes ...) const [with _Tp = A; _Res = void; _Class = B; _ArgTypes = {}]':
functional:608:42: required from '_Res std::_Mem_fn<_Res (_Class::*)(_ArgTypes ...)const>::operator()(_Tp&, _ArgTypes ...) const [with _Tp = A; _Res = void; _Class = B; _ArgTypes = {}]'
test.cpp:21:11: required from here
functional:586:13: error: no match for 'operator*' (operand type is 'A')
{ return ((*__ptr).*__pmf)(std::forward<_ArgTypes>(__args)...); }
^
Aurait-il été possible de mettre en œuvre std::mem_fn
de telle sorte que ce cas d'utilisation fonctionne comme il le fait avec l'emballage roulé à la main?