在 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++ 中推导两个类的共享基数 的相关文章

  • 在 LINQ 查询中返回不带时间的日期

    我正在编写一个查询 我想计算按日期联系我们的呼叫中心的次数 看起来很简单 但由于联系日期字段是日期时间字段 我得到了时间 因此当我按联系日期 时间 分组时 每个联系日期实例的计数为 1 所以 我想只按日期分组 而不按时间分组 下面是我用来查
  • 创建 DirectoryEntry 实例以供测试使用

    我正在尝试创建 DirectoryEntry 的实例 以便可以使用它来测试将传递 DirectoryEntry 的一些代码 然而 尽管进行了很多尝试 我还是找不到实例化 DE 并初始化它的 PropertyCollection 的方法 我有
  • 属性对象什么时候创建?

    由于属性实际上只是附加到程序集的元数据 这是否意味着属性对象仅根据请求创建 例如当您调用 GetCustomAttributes 时 或者它们是在创建对象时创建的 或者 前两个的组合 在由于 CLR 的属性扫描而创建对象时创建 从 CLR
  • 自动从 C# 代码进行调试过程并读取寄存器值

    我正在寻找一种方法来读取某个地址的 edx 注册表 就像这个问题中所问的那样 读取eax寄存器 https stackoverflow com questions 16490906 read eax register 虽然我的解决方案需要用
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在C++中实现模板类协变?

    是否可以以这样一种方式实现类模板 如果模板参数相关 一个对象可以转换为另一个对象 这是一个展示这个想法的例子 当然它不会编译 struct Base struct Derived Base template
  • 如何针对 Nancy 中的 Active Directory 进行身份验证?

    这是一篇过时的文章 但是http msdn microsoft com en us library ff650308 aspx paght000026 step3 http msdn microsoft com en us library
  • .Net Core / 控制台应用程序 / 配置 / XML

    我第一次尝试使用新的 ConfigurationBuilder 和选项模式进入 Net Core 库 这里有很多很好的例子 https docs asp net en latest fundamentals configuration ht
  • 为什么模板不能位于外部“C”块内?

    这是一个后续问题一个答案 https stackoverflow com questions 4866433 is it possible to typedef a pointer to extern c function type wit
  • A* 之间的差异 pA = 新 A;和 A* pA = 新 A();

    在 C 中 以下两个动态对象创建之间的确切区别是什么 A pA new A A pA new A 我做了一些测试 但似乎在这两种情况下 都调用了默认构造函数 并且仅调用了它 我正在寻找性能方面的任何差异 Thanks If A是 POD 类
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 像“1$”这样的位置参数如何与 printf() 一起使用?

    By man I find printf d width num and printf 2 1 d width num 是等价的 但在我看来 第二种风格应该与以下相同 printf d num width 然而通过测试似乎man是对的 为什
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 如何在内存中存储分子?

    我想将分子存储在内存中 这些可以是简单的分子 Methane CH4 C H bond length 108 7 pm H H angle 109 degrees But also more complex molecules like p
  • ListDictionary 类是否有通用替代方案?

    我正在查看一些示例代码 其中他们使用了ListDictionary对象来存储少量数据 大约 5 10 个对象左右 但这个数字可能会随着时间的推移而改变 我使用此类的唯一问题是 与我所做的其他所有事情不同 它不是通用的 这意味着 如果我在这里
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 窗体最大化时自动缩放子控件

    有没有办法在最大化屏幕或更改分辨率时使 Windows 窗体上的所有内容自动缩放 我发现手动缩放它是正确的 但是当切换分辨率时我每次都必须更改它 this AutoScaleDimensions new System Drawing Siz
  • 更改显示的 DPI 缩放大小使 Qt 应用程序的字体大小渲染得更大

    我使用 Qt 创建了一些 GUI 应用程序 我的 GUI 应用程序包含按钮和单选按钮等控件 当我运行应用程序时 按钮内的按钮和字体看起来正常 当我将显示器的 DPI 缩放大小从 100 更改为 150 或 200 时 无论分辨率如何 控件的
  • C++ 成员函数中的“if (!this)”有多糟糕?

    如果我遇到旧代码if this return 在应用程序中 这种风险有多严重 它是一个危险的定时炸弹 需要立即在应用程序范围内进行搜索和销毁工作 还是更像是一种可以悄悄留在原处的代码气味 我不打算writing当然 执行此操作的代码 相反
  • 如何将字符串“07:35”(HH:MM) 转换为 TimeSpan

    我想知道是否有办法将 24 小时时间格式的字符串转换为 TimeSpan 现在我有一种 旧时尚风格 string stringTime 07 35 string values stringTime Split TimeSpan ts new

随机推荐