这个问题是从
Passing a member function pointer to an overloaded class method into a template function
您无需阅读即可理解该问题。可能两个问题都有相同的答案。

我正在获取compiler error for below simple code

#include<set>
template<typename Return, typename T>
T ReceiveFuncPtr (Return (T::*Method)(const int&))
{
  T obj;  // Found and declared an object of actual container class
  (obj.*Method)(1);  // Some processing
  return obj;  // Returned that container class object with RVO
}
int main ()
{
  ReceiveFuncPtr(&std::set<int>::insert); // ERROR
}

该错误很有趣:
 In function 'int main()':
error: no matching function for call to 'ReceiveFuncPtr(<unresolved overloaded function type>)'
   ReceiveFuncPtr(&std::set<int>::insert); // ERROR
                                        ^
note: candidate is:
note: 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'

如果您仔细阅读说明,那么似乎编译器正在与除正确方法之外的所有其他方法匹配!在这种情况下,编译器应具有匹配的insert(const std::set<int>::value_type&) aka const int&。如果我更改ReceiveFuncPtr()来匹配其他一些重载,则跳过该重载将再次失败。

为了调试这种情况,我创建了手工版本的std::set。但是那个compiles fine:
template<typename T, typename T2 = void>
struct MySet
{
  std::pair<T,bool> insert (const T& i) { return std::pair<T,bool>(T(),true); }
  std::pair<T,bool> insert (T&& i) { return std::pair<T,bool>(T(),true); }
  void insert (std::initializer_list<T> i) { return false; }
}
int main ()
{
  ReceiveFuncPtr(&MySet<int>::insert);  // OK
}

冲浪后,我遇到了这个帖子:
What are the rules for function pointers and member function pointers to Standard functions?

尽管有关系,但不能解决问题。

问题:如果在手写库方法中传递相同的东西,为什么在标准库方法的情况下成员函数替换失败?

更新:

查看正确答案后,我确定无法使用insert。唯一的方法是丑陋的类型转换,这对于此问题来说是一个过大的杀伤力。
一种优雅的解决方案是使用std::set<int>::emplace<const int&>,它仅具有template d版本,而不同于insert,其具有template和非template版本的混合。
调用以下函数:
ReceiveFuncPtr(&std::set<int>::emplace<const int&>);

compiles fine之上。

最佳答案

问题不在于您在insert中显示的MySet函数。问题出在您遗漏的问题之一上。具体来说:

template< class InputIt >
void insert( InputIt first, InputIt last );

来自[temp.deduct.call]:



由于 &std::set<int>::insert 正是这样的重载集,因此该参数是非推导上下文,无法解析。您的MySet示例不包含insert的函数模板重载,这就是为什么它可以正常工作的原因。如果添加一个,您将看到它也将无法编译。

关于c++ - 标准库方法的成员函数指针问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31316229/

10-11 22:59
查看更多