部分专业化消歧优先链的更好模式?

2023-12-11

考虑以下一系列部分专业化:

template <typename T, typename Enable=void>
struct foo {
  void operator()() const { cout << "unspecialized" << endl; }
};

template <typename T>
struct foo<T, enable_if_t<
  is_integral<T>::value
>>{
  void operator()() const { cout << "is_integral" << endl; }
};

template <typename T>
struct foo<T, enable_if_t<
  sizeof(T) == 4
    and not is_integral<T>::value
>>{
  void operator()() const { cout << "size 4" << endl; }
};

template <typename T>
struct foo<T, enable_if_t<
  is_fundamental<T>::value
    and not (sizeof(T) == 4)
    and not is_integral<T>::value
>>{
  void operator()() const { cout << "fundamental" << endl; }
};

// etc...   

现场演示

我经常看到这种事情(事实上,其他地方的另一个 StackOverflow 答案对于类似的问题给出了相同的模式)。虽然这有效,但此代码存在一些严重的可维护性问题,并且还排除了例如,如果上述代码位于库中,则更高优先级的用户级部分专业化。表达这个想法的更好模式是什么?我觉得必须有一些东西(也许涉及继承和可变模板参数?)可以更清晰和可维护地表达这个想法。 (还假设每个专业化都是一个完整的类而不是一个简单的函子,因此重载函数不能以简单的方式工作)。


条件计数的过度增长可以通过辅助结构来解决:

#include <iostream>
#include <type_traits>

using namespace std;

template <bool ThisCondition, class ParentCondition = void, class = void>
struct condition_resolver {
   static constexpr bool is_condition_resolver = true;
   static constexpr bool parent_condition_v = !ThisCondition;
   static constexpr bool value = ThisCondition;
};

template <bool ThisCondition, class ParentCondition>
struct condition_resolver<ThisCondition, ParentCondition, enable_if_t<ParentCondition::is_condition_resolver> > {
   static constexpr bool is_condition_resolver = true;
   static constexpr bool parent_condition_v = !ThisCondition && ParentCondition::parent_condition_v;
   static constexpr bool value = ThisCondition && ParentCondition::parent_condition_v;
};

template <typename T, typename Enable=void>
struct foo {
  void operator()() const { cout << "unspecialized" << endl; }
};

template <typename T>
struct is_integral_foo: condition_resolver<is_integral<T>::value> { };

template <typename T>
struct foo<T, enable_if_t<is_integral_foo<T>::value>>{
  void operator()() const { cout << "is_integral" << endl; }
};

template <typename T>
struct has_size_four_foo: condition_resolver<sizeof(T) == 4, is_integral_foo<T>> { };

template <typename T>
struct foo<T, enable_if_t< has_size_four_foo<T>::value>>{
  void operator()() const { cout << "size 4" << endl; }
};

template <typename T>
struct is_fundamental_foo: condition_resolver<is_fundamental<T>::value, has_size_four_foo<T>> { };

template <typename T>
struct foo<T, enable_if_t<is_fundamental_foo<T>::value>>{
  void operator()() const { cout << "fundamental" << endl; } 
};

typedef char four_sized[4];

int main() {
   foo<int>()();
   foo<four_sized>()();
   foo<nullptr_t>()();
}

Output:

is_integral
size 4
fundamental

附言。 请记住void这也是很重要的,会导致编译器产生警告:sizeof(void)被认为...

Edit:

如果您确实需要使用专业化来解决条件过度增长问题,您可能会对以下内容感兴趣:

#include <iostream>
#include <type_traits>

using namespace std;

template <class Tag, int Level, class... Args>
struct concrete_condition_resolver;


template <class Tag, int Level, class... Args>
struct condition_resolver;

template <class ConditionResolver>
struct condition_resolver_parent {
   template<class CR = ConditionResolver>
   constexpr enable_if_t<CR::level != 0, bool> operator()(bool parent) {
      return (!parent && static_cast<const ConditionResolver*>(this)->condition && typename ConditionResolver::LevelUp()(true)) ||
             (parent && !static_cast<const ConditionResolver*>(this)->condition && typename ConditionResolver::LevelUp()(true));
   }

   template<class CR = ConditionResolver>
   constexpr enable_if_t<CR::level == 0, bool> operator()(bool parent) {
      return (!parent && static_cast<const ConditionResolver*>(this)->condition) ||
             (parent && !static_cast<const ConditionResolver*>(this)->condition);
   }
};

template <class Tag, int Level, class... Args>
struct condition_resolver: concrete_condition_resolver<Tag, Level, Args...>, condition_resolver_parent<condition_resolver<Tag, Level, Args...>> {
   using LevelUp = condition_resolver<Tag, Level - 1, Args...>;
   using tag = Tag;
   static constexpr int level = Level;
   constexpr condition_resolver() {}
};


struct foo_tag { };

template <class First, class... Args>
struct concrete_condition_resolver<foo_tag, 0, First, Args...> {
   static constexpr bool condition = is_integral<First>::value;
};

template <class First, class... Args>
struct concrete_condition_resolver<foo_tag, 1, First, Args...> {
   static constexpr bool condition = sizeof(First) == 4;
};

template <class First, class... Args>
struct concrete_condition_resolver<foo_tag, 2, First, Args...> {
   static constexpr bool condition = is_fundamental<First>::value;
};

template <typename T, typename = void>
struct foo;

template <typename T>
struct foo<T, enable_if_t<condition_resolver<foo_tag, 0, T>()(false)>>{
  void operator()() const { cout << "is_integral" << endl; }
};

template <typename T>
struct foo<T, enable_if_t<condition_resolver<foo_tag, 1, T>()(false)>>{
  void operator()() const { cout << "size 4" << endl; }
};

template <typename T>
struct foo<T, enable_if_t<condition_resolver<foo_tag, 2, T>()(false)>>{
  void operator()() const { cout << "is_fundamental" << endl; }
};


typedef char four_sized[4];

int main() {
   foo<int>()();
   foo<four_sized>()();
   foo<nullptr_t>()();
}

这种方法甚至适用于使用enable_if的重载函数,而部分特化仅处理结构......

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

部分专业化消歧优先链的更好模式? 的相关文章

  • 成员字段、构建顺序

    在 C 中 当执行如下所示的操作时 构造顺序是否得到保证 Logger Logger kFilePath logs runtime log logFile kFilePath 是的 施工顺序始终得到保证 但是 不能保证它与对象在初始值设定项
  • 如何使用最小起订量模拟私有只读 IList 属性

    我试图嘲笑这个列表 private readonly IList
  • 无需登录即可在 Intranet 上获取 Web 应用程序的域\用户名

    我的 Intranet 上有一个 Web 应用程序 VS 2005 有几个页面不需要用户登录应用程序 反馈和默认页面 我正在尝试获取要显示和 或发送反馈的域名和用户名 有没有一种方法可以在不需要用户登录的情况下执行此操作 我试过了this
  • 是否有可能将 *.pdb 文件包含到发布版本中以查看错误行号?

    我做了一个项目 所有设置都是默认的 当我在调试模式 构建配置 调试 下运行它并遇到异常时 它转储到我的自定义日志记录机制 其中包含错误行号 但是当我运行发布构建时 记录相同的异常 没有行号 只有方法抛出和记录调用堆栈 是否有可能在发布配置
  • ASMX Web 服务,测试表单仅在本地计算机上适用于一种 WebMethod

    我有一个正在测试的 ASMX WebService 并且在大多数方法上我都可以使用测试表单进行测试 然而 我确实有一种方法 测试表上写着 The test form is only available for requests from t
  • c 使用 lseek 以相反顺序复制文件

    我已经知道如何从一开始就将一个文件复制到另一个文件 但是我如何修改程序以按相反的顺序复制它 源文件应具有读取访问权限 目标文件应具有读写执行权限 我必须使用文件控制库 例如 FILE A File B should be ABCDEF FE
  • 多线程 - 比单线程慢

    当我使用多个线程而不是单线程运行程序时 它会变慢 不是应该更快吗 该程序应该遍历从起始目录开始的所有目录 并查找并打印所有名为 X 的文件 代码如下 while done pthread mutex lock lock if list is
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 如果项目包含多个文件夹,如何使用 Add-Migration

    我想Add Migration使用我的 DbContext 但出现错误 The term add migration is not recognized as the name of a cmdlet function script fil
  • List 或其他类型上的 string.Join

    我想将整数数组或列表转换为逗号分隔的字符串 如下所示 string myFunction List
  • 使用联合对 IP 地址进行多种解释?

    在工作中 我们使用以下构造来将 IP 地址解释为 4 字节数组或 32 位整数 union IPv4 std uint32 t ip std uint8 t data 4 这很好用 但是读完这本书的第 97 章 不要使用联合来重新解释表示
  • XCode std::thread C++

    对于学校的一个小项目 我需要创建一个简单的客户端 服务器结构 它将在路由器上运行 使用 openWRT 并且我试图在这个应用程序中使用线程做一些事情 我的 C 技能非常有限 所以我在internet https stackoverflow
  • 如何使 WinForms UserControl 填充其容器的大小

    我正在尝试创建一个多布局主屏幕应用程序 我在顶部有一些按钮链接到应用程序的主要部分 例如模型中每个实体的管理窗口 单击这些按钮中的任何一个都会在面板中显示关联的用户控件 面板包含用户控件 而用户控件又包含用户界面 WinForms User
  • 在 lua 中加载 C++ 模块时出现“尝试索引字符串值”错误

    我正在尝试使用 lua 用 C 编写的函数 下面给出的是cpp文件 extern C include lua h include lauxlib h include lualib h static int add 5 lua State L
  • 如何使用“路径”查询 XDocument?

    我想查询一个XDocument给定路径的对象 例如 path to element I want 但我不知道如何继续 您可以使用以下方法System Xml XPath Extensions http msdn microsoft com
  • C# 模式匹配

    我对 C 有点陌生 我正在寻找一个字符串匹配模式来执行以下操作 我有一个像这样的字符串 该书将在 唐宁街 11 号接待处 并将由主要医疗保健人员参加 我需要创建一个 span 标签来使用 startIndex 和 length 突出显示一些
  • 包含从代码隐藏 (ASP.NET C#) 到 ASPX 中的图像概述的图像列表 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • C# 和断点 - 这里有魔术师吗?

    我有这个 public static void ByLinkText string text for var i 0 i lt 50 i try Setup Driver FindElement By LinkText text Click
  • 在两个点之间创建一条曲线,每个点都具有标准化向量

    因此 我需要一种写入方法来在两点之间创建一条曲线 每个点都有一个指向任意方向的归一化向量 我一直在尝试设计这样一种方法 但一直无法理解数学 在这里 由于一张图片胜过一千个文字 这就是我所需要的 在图中 矢量垂直于红线 我相信向量需要进行相同
  • 如何获取运行或段落的高度

    我找到了Run or Paragraph in FlowDocument现在我需要知道HEIGHT of it i e while navigator CompareTo flowDocViewer Document ContentEnd

随机推荐

  • 如何将 WSO2 API Manager (AM) 1.10.0 与 PingFederate SAML 2.0 集成?

    如何将 WSO2 am 1 10 0 与 PingFederate SAML 2 0 集成 有什么指示吗 在 WSO2 网站上 我只看到了有关如何在 WSO2 产品中设置 SSO 的文档 https docs wso2 com displa
  • EditText 的 onFocusChange 中的 setSelection

    通常 当单击视图时 文本光标会设置在您单击的位置附近 我尝试将其始终设置为末尾 超过最后一个字符 但除非操作被延迟 否则它不会执行任何操作 下列 new OnFocusChangeListener Override public void
  • Electron-builder 没有捆绑 python 文件

    这是我的目录结构renderer js包含在index html python 脚本visitor py and download py被称为来自renderer js via 蟒蛇壳 一旦我捆绑 它就无法找到Python脚本 index
  • sql server 授予、撤销用户权限

    我编写了一个简单的 C 代码 用于连接到 sql server 数据库并执行查询 cmd new SqlCommand txtQuery Text ToString Trim con cmd ExecuteNonQuery 在我的数据库中
  • GitHub 如何更改 URL 但不重新加载? [复制]

    这个问题在这里已经有答案了 嘿 我注意到 当浏览 GitHub 存储库时 它使用 AJAX 来加载每个文件夹 文件 我明白这一切 我只是想知道他们是如何更改 URL 的 你能用 JavaScript 获取和设置 URL 吗 如果是这样 它对
  • 动画高度从下到上而不是从上到下

    如何实现反向高度动画 我怎样才能让它从元素的底部开始动画并向上移动到元素的顶部 而不是从顶部开始并向下移动的典型动画 该事件由以下条件触发a link 1 动画发生在div line 1 这是我的代码 它似乎不起作用 HTML div di
  • 使用两个域相同的数据库和不同的 WordPress 主题

    我想使用相同的数据库 内容 用户 评论 元 类别等 在我的子目录中安装另一个wordpress 我实际上想创建我的网站的移动版本 但我不想使用任何移动检测脚本或 css3 媒体查询 只是想创建我的新主题 适用于移动版本 例如 主域还有子域
  • 将数组作为数组而不是 PHP 中的 JSON 传递给 javascript

    首先 这不是重复的问题 我已经研究过一些类似的问题 大部分答案就是我现在正在使用的 这是问题设置 在 PHP 端 array array name gt a data gt array 0 gt 15 0 25 gt 18 0 35 gt
  • R 中选定列的行平均值

    让我们用著名的例子来说明这个问题iris数据集 我需要按行应用选定的函数 但仅在选定的列上应用 示例如下 library tidyverse iris gt mutate at funs scale vars vars c Species
  • 从 SQLite 数据库获取纬度和经度以在 Android MapOverlay 中使用

    如果我将一堆位置的纬度和经度存储在 SQLite 数据库中 我将如何检索这些值并将它们分别放入 OverlayItem 类中以便在 Google 的地图代码中使用 数据库名称 database 表名 place 字段位于place Tabl
  • 显示对象引用的值

    在 C 中 显示对象指针的实际值相当简单 例如 void p new CSomething cout lt lt p 有没有办法在 NET 中做这样的事情 这样做的价值只能是教育性的 例如出于演示目的 例如向学生展示一个值 而不是仅仅比较参
  • 将overlay2存储驱动程序与overlay文件系统结合使用

    Goal 我在 Live CD 中运行 docker 并且我想缓存 docker 构建的结果 主要是为了当我重新启动到此 Live CD 时使用 我的想法是建立一个overlayfs in var lib docker 所以 我有以下内容
  • SWR 挂钩不反映数据库更改

    该组件用于计算部署在 AWS Lambda 上的 Next js 应用程序中页面级别的视图数 function ViewsCounter slug slug string const data useSWR api views slug f
  • PHP摩尔斯电码转换器

    我正在用 PHP 编写一个基本的莫尔斯电码转换器 它可以接受一个字符串并将其转换为莫尔斯电码 它使用关联数组 foreach 循环和for 循环 它可以工作 除了由于某种原因它在每个转换后的字符后输出与 0 等效的莫尔斯电码 我不知道0是从
  • 在 mail.body 中查找“回车符”

    我有这样的邮件 Hello 请注意 我们在 16 点 15 分 已采取的行动 重建等 真挚地 Mr 每封邮件中的操作都会发生变化 我想要的是将操作插入到我的 Excel 中 问题是我不知道如何获得 回车符 我不知道这是否是正确的名称 这就是
  • Volley SSL - 主机名未验证

    我正在开发一个 Android 应用程序 我需要访问 HTTPS 地址 我正在使用 Volley 请求我的数据 但现在我收到此错误com android volley NoConnectionError java io IOExceptio
  • 如何实现JavaFX和非JavaFX交互?

    我已经开始使用 JavaFX 创建一个用于用户交互的窗口 以便在另一个非 JavaFX 程序中使用 我的主程序叫做Abc类 有一个 main 方法 这是一个非 JavaFX 程序 而是普通的 Java 该程序运行一些活动 然后要求用户选择一
  • java使用过多内存

    在我的一个项目中 我不断压缩小数据块 现在我发现jvm随后增长到6GB RAM 常驻 RES RAM 不是共享或虚拟等 然后由于内存不足而死掉 就好像垃圾收集器从未运行过一样 我已经提取了相关代码并将其粘贴在下面 当我运行它 java6 3
  • moment js 中的自定义长日期格式

    有没有办法根据区域设置将自定义格式代码添加到长日期时刻 例如 moment format L 是一种现有格式 它将打印区域设置的长日期 包括年份 但如果我想添加自己的排除年份的格式 如下所示 moment format LTY 它只是打印给
  • 部分专业化消歧优先链的更好模式?

    考虑以下一系列部分专业化 template