标准库方法的成员函数指针问题

2023-12-19

这个问题源于
将指向重载类方法的成员函数指针传递到模板函数中 https://stackoverflow.com/questions/31309846/passing-a-member-function-pointer-to-an-overloaded-class-method-into-a-template.
您无需阅读该内容即可理解这个问题。也许这两个问题都会有相同的答案。

我正进入(状态以下简单代码的编译器错误 http://ideone.com/wJvaxn.

#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'

如果你看一下notes 很接近,那么编译器似乎正在匹配除正确方法之外的所有其他方法!在这种情况下,编译器应该匹配insert(const std::set<int>::value_type&) aka const int&。如果我改变ReceiveFuncPtr()为了匹配其他一些重载,它会再次因跳过该重载而失败。

为了调试这种情况,我创建了手工版本std::set。但那个编译良好 http://ideone.com/ioNWD3:

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
}

上网冲浪后,我看到了这个帖子:
标准函数的函数指针和成员函数指针的规则是什么? https://stackoverflow.com/questions/13521030/what-are-the-rules-for-function-pointers-and-member-function-pointers-to-standar

虽然有关系,但并不能解决问题。

Question:为什么在标准库方法中成员函数替换会失败,而在手写类方法中却同样如此?

Update:

看完正确答案后,我确信insert不能使用。唯一的方法是丑陋的类型转换,这对于这个问题来说是一种矫枉过正的做法。
一优雅solution是使用std::set<int>::emplace<const int&>其中只有templated 版本不同于插入,它混合了template和非template版本。
调用该函数如下:

ReceiveFuncPtr(&std::set<int>::emplace<const int&>);

Above 编译良好 http://ideone.com/ps4PJb.


问题不在于insert您显示的功能MySet。问题出在您忽略的其中之一上。具体来说:

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

来自 [temp.deduct.call]:

当 P 是函数类型、函数类型指针或成员函数类型指针时:
— 如果参数是包含一个或多个函数模板的重载集,则对该参数进行处理 作为非推导的上下文。

Since 正是这样一个重载集,参数是非推导的上下文,无法解析。你的例子MySet不包含函数模板重载insert,这就是它工作正常的原因。如果添加一个,您会发现它也将无法编译。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

标准库方法的成员函数指针问题 的相关文章

随机推荐

  • 将整数转换为小数的高效算法

    CLRS 算法书的问题 31 1 12 提出了以下问题 给出一个有效的算法来转换给定的 bit 二进制 整数到十进制表示 论证如果对长度最多为 的整数进行乘法或除法 需要时间M 那么就可以及时进行二进制到十进制的转换 M lg Hint 使
  • 如何检查 Elixir 中的内存使用情况?

    Elixir 中可以检查内存使用情况吗 也许调用 Erlang 这就是我想要实现的目标 检查总内存使用情况 比方说1G of 8G Read a 4G file 检查总内存使用情况 比方说5G of 8G erlang memory tot
  • 如何确保文本框是字母数字但没有前导数字?

    我的 Web 应用程序包含一个文本框 我想限制其输入 我想阻止用户输入以下文本 以空白开头 以数字以外的内容开头 在前导字符之后包含字母数字字符 谢谢你的建议 不要以字母数字的空格开头 a zA Z 后跟 0 个或多个字母数字 a zA Z
  • Python中浮点数的分数[重复]

    这个问题在这里已经有答案了 当数字作为浮点数传递时 为什么分数的分子和分母更大 gt gt gt from fractions import Fraction gt gt gt gt gt gt a Fraction 2 34 gt gt
  • Javascript:识别是桌面Linux还是Android

    无法识别是linux桌面机还是android设备使用navigator userAgent or navigator platform因为某些 Android 设备有字符串linux同时 详情如下 Device OS navigator p
  • 启动 python 进行 Web 开发的好资源吗?

    我对学习 Python 进行 Web 开发非常感兴趣 有人能指出我正确的方向吗 我一直在 Google 上查看相关内容 但还没有真正找到任何显示正确文档以及如何开始使用的内容 有推荐的框架吗 教程 我从事 PHP 工作已有 5 年了 所以我
  • 获取复选按钮状态

    我如何获得 state of a Tkinter Checkbutton By state 我的意思是看看它是否有复选标记 当你创建它时 需要一个variable关键字参数 通过它IntVar from Tkinter 选中或取消选中该框将
  • 如何将 Kotlin 支持添加到您的 flutter 项目中?

    阅读后README文件的条形码扫描插件 https pub dev packages barcode scan我遇到了指令 这个插件是用 Kotlin 编写的 因此 需要添加Kotlin 支持您的项目 请参阅安装 Kotlin 插件 htt
  • 如何在Windows上正确使用CMAKE_MODULE_PATH

    修改此变量以便 CMake 可以找到项目指定为需求的适当模块的正确方法是什么 它似乎是自动生成的 我找不到可以以任何方式修改此路径的环境变量 我也很难找到能很好解释这一点的文档 只有 安装 CMake 包的说明 没有具体说明如何完成此操作的
  • ng-repeat 仅显示最后一个元素

    我正在使用 AngularJs 开发消息收件箱 我遇到了一个问题 我想仅显示其中的最后一个元素ng repeat 我做了一些研究 发现下面的代码应该可以工作 div class inbox ul div span recipient id
  • Flutter 将 Draggable Scrollbar 添加到 CustomScrollView?它一直给我“参数类型 CustomScrollView 无法分配给 BoxScrollView”

    一个简单的例子是 Scaffold floatingActionButton fab floatingActionButtonLocation fabLocation body Scrollbar child CustomScrollVie
  • 并发/待办事项示例不起作用

    我正在尝试 ToDo 示例 并在尝试并发处理时遇到了未处理的异常 dataservice js 包含这些行saveFailed error method if detail detail ExceptionType indexOf Opti
  • 该证书的颁发者无效 Apple Push Services

    我已创建证书以在我的应用程序中启用推送服务 但每次我尝试在钥匙串中添加证书时 添加证书后都会显示以下错误 该证书的颁发者无效 我想我已经弄清楚了这一点 我导入了新的 WWDR 证书将于 2023 年到期 https developer ap
  • Codeigniter 中国家/地区和城市的 Ajax 下拉菜单?

    我正在我们的 Codeigniter 框架中借助 ajax 使国家和城市下降 数据库的结构如下所示 Country country id country name State country id state id state name c
  • 如何在 Chrome 扩展中使用 google 创建登录信息

    我最近刚刚构建了一个插件 需要在其中集成 Google Login 我搜索并发现chrome identity使用谷歌帐户对用户进行身份验证 但这效果不佳 所以我通过使用下面的代码找到了一个解决方案 var manifest chrome
  • 使用 VBA 宏删除 PowerPoint 中的图片

    我正在使用以下 VBA 宏删除 PowerPoint 幻灯片中的所有图片 Public Function delete slide object slide no Reference existing instance of PowerPo
  • Zend Action 助手与插件

    我有一个出现在每个页面上的侧边栏 侧边栏的第一个元素是 a 登录表单 或 b 当前用户的详细信息 取决于用户是否登录 我已经阅读了一些实现此目的的方法 并计划在引导程序中初始化侧边栏占位符 当需要将用户详细信息或登录表单附加到侧边栏时 我应
  • Allegro CL 在调用(读取)函数时冻结

    每当我打电话给 read 在 Allegro Common Lisp 9 0 中 调试窗口 中断 抱歉 我想不出更清晰的术语 鼠标变成旋转的蓝色死亡轮 窗口拒绝评估任何新输入 尽管它可以仍然可以输入 IDE 的其他部分不受影响 屏幕看起来像
  • 关于加快选边速度的建议

    我正在用 C 构建一个图形编辑器 用户可以在其中放置节点 然后将它们与有向或无向边连接 完成后 A 寻路算法确定两个节点之间的最佳路径 我拥有的 具有 x y 连接节点列表以及 F G 和 H 分数的 Node 类 具有 Start Fin
  • 标准库方法的成员函数指针问题

    这个问题源于 将指向重载类方法的成员函数指针传递到模板函数中 https stackoverflow com questions 31309846 passing a member function pointer to an overlo