这个问题是从
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/