fork download
  1. #include <iostream>
  2. using namespace std;
  3.  
  4. template<class This, class Ret, class... Args>
  5. void CallMe(This* aThis, Ret(This::*aMethod)(Args...), Args... aArgs)
  6. {
  7. // Should not use std::forward without universal reference.
  8. (aThis->*aMethod)(std::forward<Args>(aArgs)...);
  9. }
  10.  
  11.  
  12. template<class This, class Ret, class... Args, class... ActualArgs>
  13. void CallMe2(This* aThis, Ret(This::*aMethod)(Args...), ActualArgs&&... aArgs)
  14. {
  15. (aThis->*aMethod)(std::forward<ActualArgs>(aArgs)...);
  16. }
  17.  
  18. class Foo
  19. {
  20. public:
  21. Foo() {}
  22. Foo(const Foo&) { cout << "copy" << endl; }
  23. Foo(Foo&&) { cout << "move" << endl; }
  24. };
  25.  
  26. class Bar
  27. {
  28. public:
  29. void Call(Foo& aFoo) { cout << "Invoke" << endl; }
  30. };
  31. int main() {
  32. Bar b;
  33. Foo f;
  34. //Will lead to a deduction ambiguity.
  35. CallMe(&b, &Bar::Call, f);
  36. //This version can fix the problem.
  37. //CallMe2(&b, &Bar::Call, f);
  38. return 0;
  39. }
Compilation error #stdin compilation error #stdout 0s 3456KB
stdin
Standard input is empty
compilation info
prog.cpp: In function 'int main()':
prog.cpp:35:26: error: no matching function for call to 'CallMe(Bar*, void (Bar::*)(Foo&), Foo&)'
  CallMe(&b, &Bar::Call, f);
                          ^
prog.cpp:5:6: note: candidate: template<class This, class Ret, class ... Args> void CallMe(This*, Ret (This::*)(Args ...), Args ...)
 void CallMe(This* aThis, Ret(This::*aMethod)(Args...), Args... aArgs)
      ^
prog.cpp:5:6: note:   template argument deduction/substitution failed:
prog.cpp:35:26: note:   inconsistent parameter pack deduction with 'Foo&' and 'Foo'
  CallMe(&b, &Bar::Call, f);
                          ^
stdout
Standard output is empty