推断 CRTP 中模板化成员函数的返回类型

2023-11-22

是否可以推断 CRTP 基类中模板化成员函数的返回类型?

虽然推断参数类型效果很好,但返回类型却失败了。考虑下面的例子。

#include <iostream>

template <typename Derived>
struct base
{
  template <typename R, typename T>
  R f(T x)
  {
    return static_cast<Derived&>(*this).f_impl(x);
  }
};

struct derived : base<derived>
{
  bool f_impl(int x)
  {
    std::cout << "f(" << x << ")" << std::endl;
    return true;
  }
};

int main()
{
  bool b = derived{}.f(42);
  return b ? 0 : 1;
}

这会产生以下错误:

  bool b = derived{}.f(42);
           ~~~~~~~~~~^
crtp.cc:7:5: note: candidate template ignored: couldn't infer template argument 'R'
  R f(T x)
    ^
1 error generated.

我的直觉假设是,如果编译器能够推断类型int对于论点f,它也应该适用于回报bool,因为这两种类型在模板实例化时都是已知的。

我尝试使用尾随返回类型函数语法,但未能找到要放入的工作表达式decltype.

EDIT 1

对于函数具有一个或多个模板化参数的情况,Dietmar Kühl 提供了一种基于使用间接层延迟模板实例化的解决方案。不幸的是,当基类函数没有任何参数时,这不起作用,如下所示:

template <typename R>
R g()
{
  return static_cast<Derived&>(*this).g_impl();
}

尝试使用相同的技术会失败,因为不存在依赖类型。人们如何处理这一案件?

EDIT 2

正如 Johannes Schaub 所指出的,C++11 具有默认模板参数,因此总是可以使g依赖于任意类型,然后应用 Dietmar 的解决方案:

template <typename T = void>
auto g() -> typename g_impl_result<Derived, T>::type
{
  return static_cast<Derived&>(*this).g_impl();
}

EDIT 3

这个问题在 C++14 中不再存在,因为我们对普通函数有返回类型推导,允许我们简单地编写:

template <typename Derived>
struct base
{
  template <typename T>
  auto f(T x)
  {
    return static_cast<Derived&>(*this).f_impl(x);
  }

  auto g()
  {
    return static_cast<Derived&>(*this).g_impl();
  }
};

struct derived : base<derived>
{
  bool f_impl(int x)
  {
    return true;
  }

  double g_impl()
  {
    return 4.2;
  }
};

一个额外的间接是你的朋友:

template <typename D, typename T>
struct f_impl_result
{
    typedef decltype(static_cast<D*>(0)->f_impl(std::declval<T>())) type;
};

template <typename Derived>
struct base
{
    template <typename T>
    auto f(T x) -> typename f_impl_result<Derived, T>::type
    {
        return static_cast<Derived&>(*this).f_impl(x);
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

推断 CRTP 中模板化成员函数的返回类型 的相关文章

  • 更快的算法来计算有多少数字可以被范围内的特定整数整除

    int a b c d 0 cin gt gt a gt gt b gt gt c for int i a i lt b i if i c 0 d cout lt
  • 必须打开存储才能执行此操作 - System.IO.Packaging.Package

    我正在使用 System IO Packaing Package 类来压缩文件 我的应用程序的多个实例可以同时运行 并读取和保存文件 当处理小文件时 一切似乎都很好 但是当涉及大文件时 如果应用程序的两个实例同时保存 我会收到一个异常 消息
  • 切换图片框可见性 C#

    为什么图片框控件的可见性属性在这里不起作用 我最初将它们设置为 false 以便在屏幕加载时它们不可见 但后来我想切换这个 我已完成以下操作 但似乎不起作用 这是一个 Windows 窗体应用程序 private void Action w
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • rand() 播种与 time() 问题

    我很难弄清楚如何使用 rand 并使用 Xcode 用 time 为其播种 我想生成 0 到 1 之间的随机十进制数 该代码为我提供了元素 1 和 2 看似随机的数字 但元素 0 始终在 0 077 左右 有什么想法吗 我的代码是 incl
  • 在通过网络发送之前压缩位图

    我正在尝试通过网络发送位图屏幕截图 因此我需要在发送之前对其进行压缩 有一个库或方法可以做到这一点吗 当您将图像保存到流时 您have选择一种格式 几乎所有位图格式 bmp gif jpg png 都使用一种或多种压缩形式 因此 只需选择适
  • 特定设备的不同字体大小

    我目前正在开发通用应用程序 我需要分别处理移动设备和桌面的文本框字体大小 我找到了一些方法 但都不能解决问题 使用 VisualStateManager 和 StateTrigger 为例
  • 用 C# 制作 Vista 风格的应用程序

    我正在运行 Windows Vista 并且希望外观看起来像常规 Vista 程序 有没有关于如何构建 Vista 风格应用程序的真正好的教程 文章 我还想学习如何使用本机代码并将其转换为 C 如this http bartdesmet n
  • 为什么重载方法在 ref 仅符合 CLS 方面有所不同

    公共语言规范对方法重载非常严格 仅允许根据其参数的数量和类型来重载方法 如果是泛型方法 则根据其泛型参数的数量进行重载 根据 csc 为什么此代码符合 CLS 无 CS3006 警告 using System assembly CLSCom
  • `cosf`、`sinf` 等不在 `std` 中 [重复]

    这个问题在这里已经有答案了 根据这里的讨论 我有报告了一个错误 https bugs launchpad net ubuntu source gcc 8 bug 1831385给 Ubuntu 开发者 编译以下示例 C 程序时 includ
  • 当在 Repository/UnitOrWork 之上使用 Service 类时,我应该在哪里放置逻辑不适合 Repository 的常用数据访问代码?

    In my 先前的问题 https stackoverflow com questions 24906548 using the generic repository unit of work pattern in large projec
  • 无法通过 LINQ to Entities 使用某些功能?

    我正在尝试使用 LINQ 查询在项目上实现搜索功能 由于数据有时包含带有重音符号和其他符号的字符 因此我创建了一种方法来删除这些字符以进行搜索 这是我的代码 var addresses from a in db Addresses join
  • Dynamics Crm:获取状态代码/状态代码映射的元数据

    在 Dynamics CRM 2011 中 在事件实体上 状态原因 选项集 也称为状态代码 与 状态 选项集 也称为状态代码 相关 例如看这个截图 当我使用 API 检索状态原因选项集时 如下所示 RetrieveAttributeRequ
  • 为什么C语言中可以使用多个分号?

    在 C 中我可以执行以下操作 int main printf HELLO WORLD 它有效 这是为什么 我个人的想法 分号是一个 NO OPERATION 来自维基百科 指示符 拥有一大串分号与拥有一个分号并告诉 C 语句已结束具有相同的
  • 是否有任何不使用公共虚拟方法的正当理由? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 是否有任何不使用公共虚拟方法的正当理由 我在某处读到我们应该避免使用公共虚拟方法 但我想向专家确认这是否是有效的声明 对于良好且稳定的 API
  • c# 替代方案中 cfusion_encrypt 中填充的密钥是什么?

    我找到了从这里复制 C 中的 cfusion encrypt 函数的答案 ColdFusion cfusion encrypt 和 cfusion decrypt C 替代方案 https stackoverflow com questio
  • 程序退出后,TcpListener Socket 仍处于活动状态

    当我的程序退出时 我试图停止 TCP 侦听器 我不关心套接字或任何活动客户端套接字上当前活动的任何数据 套接字清理代码本质上是 try myServer Server Shutdown SocketShutdown Both catch E
  • 通过 cmake 链接作为外部项目包含的 opencv 库[重复]

    这个问题在这里已经有答案了 我对 cmake 比较陌生 经过几天的努力无法弄清楚以下事情 我有一个依赖于 opencv 的项目 它本身就是一个 cmake 项目 我想静态链接 opencv 库 我正在做的是我的项目中有一份 opencv 源
  • 如何确定给定方法可以抛出哪些异常?

    我的问题和这个真的一样 找出 C 中方法可能抛出的异常 https stackoverflow com questions 264747 finding out what exceptions a method might throw in

随机推荐

  • 使用 PHP,如何访问从 Stripe API 返回的受保护的 _values 属性?

    我正在整合条纹API与 CMS 我需要归还 values查询中的属性作为数组 以便数据可用作 CMS 中的模板变量 但它始终受到保护 我一直在使用反思类获取数据 但现在我正在使用 Stripe Stripe Plan all 我必须多次调用
  • Pip 选择了错误的路径

    我使用的是 Windows 10 我摆脱了 python 3 8 并安装了 3 7 作为系统上唯一的 python 版本 当尝试使用 pip 安装库时 我现在收到错误 Fatal error in launcher Unable to cr
  • Task.WaitAll() 未按预期工作

    我正在尝试弄清楚如何使用 Task 类 过去我一直使用常规的 Thread 类 但我正在尝试掌握所有异步编程 作为示例 我创建了一个包含所有代码的主 Winforms 应用程序 我的问题的相关代码是 Relevant delegates p
  • 按钮不透明度/透明度

    主要 xml
  • 在 Vuejs 中将数据从子级传递到父级(有那么复杂吗?)

    我读过 vuejs 从子组件更新父数据 https forum vuejs org t passing data back to parent 1201 2 概念是相同的 我需要将数据对象从子级传递给父级 我用过 emit将数据传递给父组件
  • 如何使用php将数据插入tally?

    我已经使用此代码从 tally erp 9 0 获取数据
  • Web 应用程序中的静态变量

    我可以在 Web 应用程序中使用静态变量吗 static 的替代品是什么 当我在页面中使用静态变量并且多个用户使用该应用程序时 它会产生冲突数据 不正确的数据 使用静态成员有哪些限制 静态成员在内存中共享吗 考虑将共享变量存储在 HttpA
  • 如何将 font Awesome 合并到 dart 组件中?

    以下 html 在文本左侧显示了一个漂亮的相机图标 当尝试设计聚合物组件的样式时 这是如何实现的 p i class fa fa camera retro fa lg i Cool camera p 具体来说 链接应该包含在哪里 ap
  • 在 Rails 开发中加载类后代

    当我在本地进入 Rails 控制台时 我需要能够从控制器看到所有类后代 我有这个Api BaseController我所有的 Api 控制器都继承自它 我遇到的问题是 当我跳到 Rails 控制台检查后代中的 Api 控制器时 它会显示为空
  • 无法从 Ldapmain 对您进行身份验证,因为“user.name 的凭据无效”

    I use debian 9 gitlab ce 11 10 4 ce 0 通过 apt 进行综合安装 openldap 2 4 44 ldap配置 已配置 etc ldap ldap conf BASE dc serverX dc lan
  • Paramiko / scp - 检查远程主机上是否存在文件

    我正在使用 Python Paramiko 和 scp 在远程计算机上执行一些操作 我使用的一些机器要求文件在其系统上本地可用 在这种情况下 我使用 Paramiko 和 scp 来复制文件 例如 from paramiko import
  • .NET 文件系统包装库[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 由于某种原因我找不到一个 但肯定有人已经创建了一个 NET IO 库包装器 我希望能够模拟对 File Exists 等的调用 而内置的静态方法对此
  • 绑定到 DataTable 的滚动事件

    我需要绑定到设置为垂直滚动的 DataTable 的滚动事件 很明显 简单的事件绑定是行不通的 table tbody on scroll function alert 我创建了一个demo here 有谁知道可以执行此操作的 API 方法
  • .NET 中每个文件规则一个类? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我遵循这条规则 但我的一些同事不同意它 并认为如果一个类较小 它可以与其他类留在同一个文件中 我经常听到的另一个论点是 连微软都不这样做 那我们为什么要这样做呢 对此 普遍的共识是什么 在
  • 模板概念进入了 c++14 吗?

    概念是一个很好的功能 例如 当模板实例化出现问题时 它可以用可读的消息替换丑陋的编译器错误输出 不幸的是他们没有得到to C 11 有人知道它是否进入了 C 14 吗 No but 对 Bjarne Stroustrup 的采访表示它们将被
  • 如何将 FOS\RestBundle 的默认格式指定为 json?

    我对应的配置是 fos rest view view response listener force sensio framework extra view annotations false 将路线指定为确实很烦人 Route jobs
  • Python 过滤器/最大组合 - 检查空迭代器

    使用Python 3 1 我知道这个问题已经被问过很多次 用于测试迭代器是否为空的一般问题 显然 对此没有简洁的解决方案 我猜是有原因的 迭代器在被要求返回下一个值之前并不真正知道它是否为空 不过 我有一个具体的例子 希望我能从中编写出干净
  • 如何将字符串转换为 IP 地址,反之亦然

    如何转换字符串 ipAddress struct in addr 反之亦然 如何提交未签名的长 ip 地址 谢谢 Use inet ntop and inet pton 如果你需要其他方式 不使用inet ntoa inet aton 类似
  • Java 6 启动画面

    我一直无法让 Java 6 启动屏幕正常工作 我已经尝试了我能想到的一切 我的manifest mf包含 Manifest Version 1 0 X COMMENT Main Class will be added automatical
  • 推断 CRTP 中模板化成员函数的返回类型

    是否可以推断 CRTP 基类中模板化成员函数的返回类型 虽然推断参数类型效果很好 但返回类型却失败了 考虑下面的例子 include