用于重载传递的函数指针类型的表达式 SFINAE

2023-11-26

在此示例中,函数被传递给隐式实例化的函数模板。

// Function that will be passed as argument
int foo() { return 0; }

// Function template to call passed function
template<typename F>
int call(F f) {
    return f();
}

template<typename F, typename A>
int call(F f, A a) {
    return f(a);
}

int a = call(foo);

我们可以通过添加重载来破坏这段代码foo().

int foo(int i) { return 0; }

名字 ”foo" 现在不明确,该示例将不再编译。可以通过显式提供函数指针类型信息来进行编译。

int (*func_takes_void)() = foo;
int a = call(func_takes_void);

int (*func_takes_int)(int) = foo;
int b = call(func_takes_int, 0);

http://coliru.stacked-crooked.com/a/e08caf6a0ac1e6b9

是否可以推导函数指针类型?如果是这样,为什么我的下面的尝试不起作用以及正确的方法是什么?

如果这是不可能的,一个好的答案可以解释原因。

迄今为止的尝试

人类可以看到哪个foo()通过检查定义来在这两个调用中意在call<>()但编译器无法使用该信息来进行重载解析。尽管如此,信息都在那里,只需将其拉入函数模板签名即可。这对于表达式 SFINAE 来说是可能的。

在伪代码中我们想要这样:

template<IgnoreThis, typename ReturnType>
struct expr_check
{
    typedef ReturnType type;
}

template<typename F>
expr_check<expression requiring F have correct signature, result_of<F>::type>::type
call(F f);

这是在实际代码中实现的想法。

http://coliru.stacked-crooked.com/a/a3ce828d6cb16c2d

函数模板签名是:

template<typename F>
typename expr_check<sizeof(declval<F>()()), typename func_ptr_result<F>::type>::type
call(F f);

template<typename F, typename A>
typename expr_check<sizeof(declval<F>()(declval<A>())), typename func_ptr_result<F>::type>::type
call(F f, A a);

我目前拥有的内容无法编译。从编译器输出中,您可以看到在两次尝试实例化函数模板时,其中一次尝试都出现替换失败call<>()重载,另一个只是给出一个不透明的“无法推断模板参数”。

(大肠虫被编译为 C++03,但 C++11 的答案很好。)

我怀疑在实例化时call<>(), foo()没有被调用,C++ 根本不提供重载解析foo()在此背景下。可以证明这一点并不重要foo()重载是正确的,C++ 只是在这里不强制要求重载解析。另一方面,重载解析并不限于正在调用的函数。适当类型的函数指针可以选择重载foo().

相关问题

有几个问题询问有关函数指针类型重载的问题。看来这个是做不到的。我没有发现任何试图通过表达式 SFINAE 执行此操作的问题。

这似乎是最接近的相关问题。

有没有办法推断函数指针模板参数的值?

额外的迂腐

标题中使用的“函数指针”是正确的短语吗? “函数参考”会更准确吗?


你能得到的最接近的可能是这样的:

struct sfoo
{
  template<typename... args>
  void operator() (args&&... a)
  { 
    foo(std::forward<args>(a)...);
  }
};

并通过sfoo (or sfoo()) 代替foo around.

也就是说,创建一个函数对象类型,将整个重载集封装在模板化中operator().

然后,您将获得同一参数的模板实例化,而不是对不存在的模板参数进行重载解析,这是可以的。

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

用于重载传递的函数指针类型的表达式 SFINAE 的相关文章

  • 无法在更新面板中找到上传的文件

    aspx
  • 将内核链接到 PTX 函数

    我可以使用 PTX 文件中包含的 PTX 函数作为外部设备函数 将其链接到另一个应调用该函数的 cu 文件吗 这是另一个问题CUDA 将内核链接在一起 https stackoverflow com questions 20636800 c
  • 错误 C2064:术语不计算为采用 1 个参数的函数

    class Student bool Graduate return m bGraduate class School vector
  • 设置外部应用程序焦点

    在 VB NET 中 您可以使用以下命令将焦点设置到外部应用程序 AppActivate Windows Name or AppActivate processID As Integer 现在 如果您这样做 则效果很好 Dim intNot
  • F# 内联如何工作?

    对于 F 我的理解是您可以使用 inline 关键字在调用站点执行类型专门化 那是 val inline a gt b gt c when a or b static member a b gt c 约束条件是 a or b必须有一个静态成
  • .NET 中 IEqualityComparer 中 GetHashCode 的作用是什么?

    我试图了解 IEqualityComparer 接口的 GetHashCode 方法的作用 下面的例子取自MSDN using System using System Collections Generic class Example st
  • 让 GCC/Clang 使用 CMOV

    我有一个简单的标记值联合 这些值可以是int64 ts or doubles 我正在对这些联合进行加法 但需要注意的是 如果两个参数都代表int64 t值 那么结果也应该有一个int64 t value 这是代码 include
  • 编译器在函数名称前添加下划线前缀的原因是什么?

    当我看到 C 应用程序的汇编代码时 如下所示 emacs hello c clang S O hello c o hello s cat hello s 函数名称以下划线作为前缀 例如callq printf 为什么这样做以及它有什么优点
  • 适用于 Windows 的键值数据库?

    除了 MongoDB 和 Memcached 之外 Windows 上还运行哪些键值存储 我见过的大多数似乎只能在 Linux 上运行 Hypertable Redis Lightcloud 相关链接 是否有经过商业验证的云存储 Key g
  • 在 Asp.Net 模板中转义内联代码块

    我有一个页面 我希望在其中呈现以下 html 一个小的 JS 模板 然而 Asp NET 预处理器正在拾取 我已经设法通过文字控件来做到这一点 并在后面的代码中设置它的文本 我理想地希望将其保留在 aspx 页面中 这是我能找到的最好的解决
  • 在标准库中静态链接时如何支持动态插件?

    假设一个应用程序myapp exe是使用构建的g 它使用标志 static libstdc 这样就可以安装在没有环境的情况下libstdc so myapp exe还添加了对某些功能的插件支持plugf可以通过动态加载dlopen来自共享库
  • PHP:分离业务逻辑和表示逻辑,值得吗? [复制]

    这个问题在这里已经有答案了 可能的重复 为什么要在 PHP 中使用模板系统 https stackoverflow com questions 436014 why should i use templating system in php
  • C语言:如何获取使用strtok()一次后剩余的字符串

    我的字符串是 A B C D E 分隔符是 如何获取执行 strtok 一次后剩余的字符串 即 B C D E char a A B C D E char separator char b strtok a separator printf
  • C语言中如何将整数转换为字符? [复制]

    这个问题在这里已经有答案了 C语言中如何将整数转换为字符 C 中的字符已经是数字 字符的 ASCII 代码 无需转换 如果要将数字转换为相应的字符 只需添加 0 即可 c i 0 0 是 ASCii 表中的一个字符
  • 如何从句柄确定进程是 32 位还是 64 位?

    如何从使用 OpenProcess 获取的进程句柄中获取信息 无论进程是 32 位还是 64 位 是的 IsWow64Process 毫无用处 令人烦恼 它的真正意思是 启用了 32 位模拟 如果您在 32 位操作系统上运行 则返回 fal
  • 派生类的聚合初始化

    以下代码无法使用 Visual Studio2017 或在线 GDB 进行编译 我期望它能够编译 因为迭代器只是一个具有类型的类 并且它是从公共继承的 这是不允许的还是在 VS2017 中不起作用 template
  • 检测用户是否正在滚动 dataGridView 滚动条

    我正在更新一个dataGridView与一个新的数据表使用 dataGridView1 DataSource table 但是 我不想在用户滚动 dataGridView 时执行此操作 如何检查滚动条是否正在滚动或已完成滚动 即拖动而不是单
  • C# 记录类型:记录子类之间的相等比较

    给定父记录类型 public record Foo string Value 和两个记录子类Bar and Bee我想知道是否可以实施Equals在基类中 因此 Foo Bar 或 Bee 的实例都被考虑equal基于Value 两者都与E
  • Azure Function App Azure 服务总线触发器触发两次

    我使用带有服务总线触发器的 Azure Function Apps 来读取服务总线并对服务总线消息的内容执行操作 服务总线接收 JSON 序列化对象 然后将 JSON 消息反序列化回 Function App 中的对象 然而 由于某种原因
  • 如何通过Task.ContinueWith创建传递?

    我想在原始任务结束时添加一个任务 但想保留原始结果和类型 附加任务仅用于记录目的 例如写入控制台等 例如 Task Run gt DateTime Now Hour gt 12 Hey throw new Exception Continu

随机推荐

  • 如何从 leiningen 项目中排除 jar?

    在使用 Leiningen 时 我遇到了以下突然错误 线程 main 中的异常 java lang NoSuchMethodError org apache tools ant util FileUtils getFileUtils Lor
  • 更新部署文件后 Antlr3.runtime 访问被拒绝

    我们有一个 ASP NET 应用程序 是由一位前员工编写的 到目前为止我一直用胶带将其固定在一起 该应用程序是用 MVC NHibernate 和其他一些进程编写的 我们的其他应用程序都没有使用这些进程 所以我对如何支持这些进程知之甚少 更
  • 按第一项对嵌套列表进行排序 - itemgetter 不起作用

    我有一本字典 已转换为列表 以便我可以按第一项进行排序 字典中的键是一个字符串 数字 值是一个在列表中维护的整数 字典转换的列表如下所示 228055 1 228054 1 228057 2 228056 1 228051 1 228050
  • 异步 Google 地图 API v3 未定义不是函数 [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我正在编写一个应用程序 它使用手工构建的框架异步加载 Google 地图 当我加载地图时
  • Node JS 中 Socket 和 EventEmitter 的异同

    我对 Node js 中的 Socket io 和 EventEmitter API 有点困惑 是的 我对事件驱动的 NodeJS 编程很陌生 这两者之间有什么显着差异吗 或者一个已经超越了另一个 它们的设计目的是相同还是不同 任何示例 资
  • 如何在 UITableViewCell 中获取透明附件视图? (带屏幕截图)

    我使用笔尖中的自定义 UITableViewCell 附件视图是详细信息披露指示器 问题是附件视图后面的 UITableViewCell 的背景颜色没有被渲染 参见下面的图像 源 有什么线索吗 另外 这里有一些我尝试过但没有成功的事情 不起
  • 设置在 matplotlib 中使用 plt.subplots 创建的图形的高度和宽度?

    在 matplotlib 中 我知道如何设置图形的高度 宽度和 DPI fig plt figure figsize 4 5 dpi 100 然而 似乎如果我想创建小的多个图 我无法创建这样的图形 我必须使用这个 fig subplots
  • ASP.NET MVC - 使用 ViewData 将 Json 字符串传递给视图

    我正在尝试使用 ViewData 将 Json 传递到我的视图 控制器 ViewData JsonRegionList Json RegionService GetActiveRegions view input UserRegion au
  • 非中心卡方概率和非中心参数

    如何获得非中心参数的值 对于不同的临界值和自由度 该参数的概率恰好为 0 9 例如 显着性水平 0 05 且自由度为 1 临界值 3 84 时 ncp 必须等于 10 50742 才能获得 0 9 的概率 1 pchisq 3 841459
  • Android 深度链接与自定义 URI

    我在清单中定义了以下内容
  • “PHP 通知:未定义的属性”[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 我收到这个奇怪的错误 你会说 为什么奇怪 你只是没有这
  • 运行一个进程并退出而不等待它

    在 Windows 下的 Python 中 我想在单独的进程中运行一些代码 我不希望家长等待它结束 尝试过这个 from multiprocessing import Process from time import sleep def c
  • C# 中委托不可变的目的是什么?

    我正在看一本图解C 2012的Combining Delegates一节 没有注意到这一点吗 代表们的目的是一成不变的 合并代表 到目前为止 您见过的所有代表都只有 其调用列表中的单个方法 代表可以 合并 通过使用加法运算符 运算的结果是
  • Redis集群与Spring boot集成

    我有一个具有主服务器 从服务器和 3 个哨兵服务器的 Redis 集群 主服务器和从服务器映射到 dns 名称为 node1 redis dev com node2 redis dev com redis服务器版本是2 8 我将以下内容包含
  • 找出Windows服务正在运行的进程名称.NET 1.1

    我们正在使用一个写得不好的 Windows 服务 当我们试图从代码中停止它时 它会挂起 因此 我们需要找到与该服务相关的进程并将其杀死 有什么建议么 您可以使用System Management MangementObjectSearche
  • “每个表只能有一个 IDENTITY 列” - 为什么?

    每个表只能有一个 IDENTITY 列 为什么会这样呢 以车辆为例 存在唯一的底盘号以及唯一的车牌号 为了描述这个场景sql服务器我们需要对其中一个列进行自定义实现 相反 在Oracle一张桌子上可以有任意数量的序列 为什么对 IDENTI
  • 如何在html动作链接中插入图像? ASP.NET MVC

    我的 web 项目上有来自 html 操作链接的导航和许多链接 它们很丑 有下划线 我想插入一些带有名称的图像或使用操作链接的样式 是否可以 怎么做 谢谢并保重 拉吉姆斯 您可以使用 css 删除下划线或放置背景图片 否则你也可以像这样创建
  • 来自元组的构造函数参数

    如果我有一个像这样的结构 struct Thing int x int y bool a bool b 然后我可以创建一个Thing对象通过这样做 Thing t 1 2 true false 但是 如果我有一个元组 那么我会做类似的事情
  • 如何在 Angular 2 中使用 SheetJS (js-xlsx)

    我正在学习 angular2 我想使用js xlsx我的项目中的库 我安装了xlsxnpm install xlsx和jszipnpm install jszip并将它们添加到我的index html中 并添加了打字稿定义tsd insta
  • 用于重载传递的函数指针类型的表达式 SFINAE

    在此示例中 函数被传递给隐式实例化的函数模板 Function that will be passed as argument int foo return 0 Function template to call passed functi