在 C++ 中推导两个类的共享基数

2023-12-26

我几乎可以肯定,如果没有的话,我正在寻找的东西就无法完成反射,这还没有出现在语言中。但有时我会对 SO 中的特殊答案感到惊讶,所以让我们尝试一下。

是否可以推导出具有公共共享基类的两种类型的“common_base”,因此以下内容是可能的(伪代​​码!--没有 common_base_t 在语言中,这是magic我正在努力实现):

template<typename T1, typename T2>
const common_base_t<T1, T2>& foo(const T1& a1, const T2& a2) {
    if(a1 < a2) return a1;
    return a2;
}

注意a1 and a2以上不分享common_type,仅仅因为是兄弟(共享相同的基数),因此我们不能使用三元运算符。

另请注意,将上述返回类型更改为const auto&没有解决问题(它不会编译:自动返回类型的扣除不一致).

这是一个简单的实现,要求调用者声明预期的返回类型:

template<typename R>
const R& foo(const auto& a1, const auto& a2) {
    if(a1 < a2) return a1;
    return a2;
}

然后我们可以这样调用它:

MyString1 s1 = "hello"; // MyString1 derives from std::string
MyString2 s2 = "world"; // MyString2 also derives from std::string
std::cout << foo<std::string>(s1, s2); // ok we return const lvalue ref
                                       // pointing to one of the above objects

造成这种情况的原因有很多probably如果不提供预期的回报值,就无法实现。但也许可以实现somehow?


标准库的std::common_reference<> https://cppreference.fasanowood.com/en/cpp/types/common_reference.html非常接近您想要的,并且可以说是您想要的foo()应该使用函数,因为它清楚地表达了所需的语义:

template<typename T1, typename T2>
std::common_reference_t<const T1&, const T2&> foo(const T1& a1, const T2& a2) {
    if(a1 < a2) return a1;
    return a2;
}

不幸的是,对于这个特定的用例,它不能开箱即用,因为它无法检测公共基础,除非其中一种类型派生于另一种类型。

但是,您可以通过专门化来给出提示std::common_type https://en.cppreference.com/w/cpp/types/common_type。就像这样:

namespace std {
    template<>
    struct common_type<MyString1, MyString2> {
        using type = std::string;
    };
}

它会“正常工作”。您可以在这里看到它的实际效果:https://gcc.godbolt.org/z/e3PrecPac https://gcc.godbolt.org/z/e3PrecPac.

Edit:值得一提的是,根据您的情况,您还可以创建通用的专业化std::common_type对于从给定基派生的所有类型:

struct SomeBase {};

namespace std {
    template<std::derived_from<SomeBase> T1, std::derived_from<SomeBase> T2>
    struct common_type<T1, T2> {
        using type = SomeBase;
    };
}

不过,我会对此略加讨论。这是一个潜在的非常广泛和广泛的部分专业化。它很容易导致歧义,特别是如果多次这样做的话。

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

在 C++ 中推导两个类的共享基数 的相关文章

  • 静态只读字符串数组

    我在我的 Web 应用程序中使用静态只读字符串数组 基本上数组有错误代码 我将所有类似的错误代码保存在一个数组中并检查该数组 而不是检查不同常量字符串中的每个错误代码 like public static readonly string m
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 适合初学者的良好调试器教程[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 有谁知道一个好的初学者教程 在 C 中使用调试器 我感觉自己好像错过了很多 我知道怎么做 单步执行代码并查看局部变量 虽然这常常给我带来问
  • 在c#中执行Redis控制台命令

    我需要从 Redis 控制台获取 客户端列表 输出以在我的 C 应用程序中使用 有没有办法使用 ConnectionMultiplexer 执行该命令 或者是否有内置方法可以查找该信息 CLIENT LIST是 服务器 命令 而不是 数据库
  • C++ 是否可以在 MacOS 上与 OpenMP 和 boost 兼容?

    我现在已经尝试了很多事情并得出了一些结论 也许 我监督了一些事情 但似乎我无法完成我想要的事情 问题是 是否有可能使用 OpenMP 和 boost 在 MacOS High Sierra 上编译 C 一些发现 如果我错了请纠正我 Open
  • IdentityServer 4 对它的工作原理感到困惑

    我阅读和观看了很多有关 Identity Server 4 的内容 但我仍然对它有点困惑 因为似乎有很多移动部件 我现在明白这是一个单独的项目 它处理用户身份验证 我仍然不明白的是用户如何注册它 谁存储用户名 密码 我打算进行此设置 Rea
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 将 Long 转换为 DateTime 从 C# 日期到 Java 日期

    我一直尝试用Java读取二进制文件 而二进制文件是用C 编写的 其中一些数据包含日期时间数据 当 DateTime 数据写入文件 以二进制形式 时 它使用DateTime ToBinary on C 为了读取 DateTime 数据 它将首
  • C# 存档中的文件列表

    我正在创建一个 FileFinder 类 您可以在其中进行如下搜索 var fileFinder new FileFinder new string C MyFolder1 C MyFolder2 new string
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • 使用valgrind进行GDB远程调试

    如果我使用远程调试gdb我连接到gdbserver using target remote host 2345 如果我使用 valgrind 和 gdb 调试内存错误 以中断无效内存访问 我会使用 target remote vgdb 启动
  • 在视口中查找 WPF 控件

    Updated 这可能是一个简单或复杂的问题 但在 wpf 中 我有一个列表框 我用一个填充数据模板从列表中 有没有办法找出特定的数据模板项位于视口中 即我已滚动到其位置并且可以查看 目前我连接到了 listbox ScrollChange
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • 使 Guid 属性成为线程安全的

    我的一个类有一个 Guid 类型的属性 该属性可以由多个线程同时读写 我的印象是对 Guid 的读取和写入不是原子的 因此我应该锁定它们 我选择这样做 public Guid TestKey get lock testKeyLock ret
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 在 Windows Phone silverlight 8.1 上接收 WNS 推送通知

    我有 Windows Phone 8 1 silverlight 应用程序 我想使用新框架 WNS 接收通知 我在 package appxmanifest 中有
  • 为boost python编译的.so找不到模块

    我正在尝试将 C 代码包装到 python 中 只需一个类即可导出两个函数 我编译为map so 当我尝试时import map得到像噪音一样的错误 Traceback most recent call last File
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 如何将十六进制字符串转换为无符号长整型?

    我有以下十六进制值 CString str str T FFF000 如何将其转换为unsigned long 您可以使用strtol作用于常规 C 字符串的函数 它使用指定的基数将字符串转换为 long long l strtol str

随机推荐