0

Consider this as an extension of my previous question:
How to pass a member function pointer to an overloaded method in a template function?

I have a function which receives pointer to class method:

template<typename Return, typename T>
T ReceiveFuncPtr (Return (T::*Method)(const int&))
{
  T obj;
  (obj.*Method)(1);
  return obj;
}

It works fine for a handwritten class such as:

template<typename X, typename = void>
struct A
{
  std::pair<X,bool> foo (const X& i) { return std::pair<X,bool>(X(),true); } // choice
  void foo (std::initializer_list<X> i) { return 0; } 
};

int main ()
{
  ReceiveFuncPtr(&A<int>::foo); // OK
}

However, I am unable to pass std::set<int>::insert(const int&)

ReceiveFuncPtr(&std::set<int>::insert); 

Above statement results in:

error: no matching function for call to ‘ReceiveFuncPtr(<unresolved overloaded function type>)’
   ReceiveFuncPtr(&std::set<int>::insert); // ERROR
                                        ^   
note: candidate: template<class Return, class T> T ReceiveFuncPtr(Return (T::*)(const int&))
 T ReceiveFuncPtr (Return (T::*Method)(const int&))
   ^   
note:   template argument deduction/substitution failed:
note:   mismatched types ‘const int&’ and ‘std::initializer_list<int>’
   ReceiveFuncPtr(&std::set<int>::insert); // ERROR
                                        ^
note:   mismatched types ‘const int&’ and ‘std::set<int>::const_iterator {aka std::_Rb_tree_const_iterator<int>}’
note:   mismatched types ‘const int&’ and ‘std::set<int>::const_iterator {aka std::_Rb_tree_const_iterator<int>}’
note:   mismatched types ‘const int&’ and ‘std::set<int>::value_type&& {aka int&&}’
note:   couldn't deduce template parameter ‘Return’

What is the correct way to pass such method?

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336
  • Perhaps because your `ReceiveFuncPtr` expects a function of type `f(int)` and you're passing `f(const int&)`. – Amit Jul 09 '15 at 06:51
  • 1
    the method's signature should be `Return (T::*Method)(const int&)` and then resolved with `ReceiveFuncPtr(static_cast::iterator,bool>(std::set::*)(const int&)>(&std::set::insert));`, but it's ugly and not portable, why are you using a function pointer instead of lambda expressions? – Piotr Skotnicki Jul 09 '15 at 06:51
  • 1
    @iammilind http://ideone.com/VzqHWT – Piotr Skotnicki Jul 09 '15 at 07:03
  • @PiotrS., that's a good effort again. However then the question will become of "language lawyer". You can see that it works good in the similar setup for `template class A`. Why it doesn't work in the same way for `std::set`. The additional typecast you suggested makes it work, but the code becomes verbose. – iammilind Jul 09 '15 at 07:07
  • @iammilind because overloaded functions must be resolved at a call site – Piotr Skotnicki Jul 09 '15 at 07:08
  • * (unless they can be resolved based on the signature of a function that is called which is not the case here, as template argument deduction only deduces types) – Piotr Skotnicki Jul 09 '15 at 07:31
  • 1
    Please read the [member.functions] sections. It contains footnote 188, which says that *" the address of a member function of a class in the C ++ standard library has an unspecified type."* See http://stackoverflow.com/q/13521030/ cc @PiotrS. Forming a pointer to a member function of a StdLib type is usually not a good idea because of portability. – dyp Jul 09 '15 at 07:36
  • @dyp I said it in my first comment: *"but it's ugly and not portable*" – Piotr Skotnicki Jul 09 '15 at 07:46
  • @PiotrS. Ah, sorry, I've only read the (good) remark about lambdas. – dyp Jul 09 '15 at 07:52
  • @PiotrS., actually I don't want to use lambdas in this specific case. Don't go by the name of the function. This function is intended to receive a standard method name e.g. `std::set::insert`, `std::vector::push_back()` and find our that which container it belongs to; i.e. `set` and `vector` in above cases and create an object, call the given method on it with some criteria an return the object. But now with `@dyp`'s link it seems that for standard libraries the rules are different. And I can not achieve the thing I want right now. – iammilind Jul 09 '15 at 09:32
  • @dyp, I have continued the discussion by posting a new question: [Member function pointer issue with standard library methods](http://stackoverflow.com/questions/31316229/member-function-pointer-issue-with-standard-library-methods) – iammilind Jul 09 '15 at 11:34

0 Answers0