iam*_*ind 6 c++ templates member-function-pointers standard-library c++11
从
将成员函数指针传递给模板函数的重载类方法产生了这个问题.
你不需要阅读它来理解这个问题.可能两个问题都有相同的答案.
#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
}
Run Code Online (Sandbox Code Playgroud)
错误很有趣:
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'
Run Code Online (Sandbox Code Playgroud)
如果仔细观察音符,那么看起来编译器匹配除了正确的方法之外的所有其他方法!在这种情况下,编译器应该匹配insert(const std::set<int>::value_type&)aka const int&.如果我改变ReceiveFuncPtr()匹配其他一些重载,它将通过跳过该重载再次失败.
为了调试这种情况,我创建了手工版本std::set.但编译很好:
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
}
Run Code Online (Sandbox Code Playgroud)
冲浪之后,我遇到了这个帖子:
标准函数的函数指针和成员函数指针的规则是什么?
虽然它是相关的,但它并没有解决问题.
问题:为什么在标准库方法的情况下,当手写类方法传递相同的东西时,成员函数替换失败?
更新:
看了正确答案后,我确信insert无法使用.唯一的方法是丑陋的类型转换,这对这个问题来说太过分了.
一个优雅的解决方案是使用std::set<int>::emplace<const int&>只有templated版本的插件,它具有混合template和非template版本.
调用如下函数:
ReceiveFuncPtr(&std::set<int>::emplace<const int&>);
Run Code Online (Sandbox Code Playgroud)
以上编译很好.
问题不在于insert您展示的功能MySet.问题在于你省略了哪一个.特别:
template< class InputIt >
void insert( InputIt first, InputIt last );
Run Code Online (Sandbox Code Playgroud)
来自[temp.deduct.call]:
当P是函数类型时,指向函数类型的指针或指向成员函数类型的指针:
- 如果参数是包含一个或多个函数模板的重载集,则该参数将被视为非推导上下文.
由于&std::set<int>::insert恰好是这样的重载集,因此该参数是非推导的上下文,无法解析.您的示例MySet不包含函数模板重载insert,这就是它工作正常的原因.如果你添加一个,你会发现它也将无法编译.
| 归档时间: |
|
| 查看次数: |
317 次 |
| 最近记录: |