关于模板专业化和继承的良好实践

2024-02-05

模板专业化不考虑继承层次结构。例如,如果我专门设计一个模板Base并实例化它Derived,不会选择专业(参见下面的代码(1))。

这可能是一个主要障碍,因为它有时会导致违反里氏替换原则。例如,在工作时这个问题 https://stackoverflow.com/q/7917853/20984,我注意到我无法使用 Boost.Range 算法std::sub_match虽然我可以std::pair. Since sub_match公开继承自pair,常识表明我可以用sub_match到处都是pair使用,但是由于使用模板专业化的特征类而失败。

我们可以通过使用部分模板专业化以及enable_if and is_base_of(参见代码(2))。我是否应该始终青睐此解决方案而不是完全专业化,尤其是在编写库代码时?我观察到的这种方法有什么缺点吗?这是您经常使用或经常看到的做法吗?


示例代码

(1)
#include <iostream>

struct Base {};
struct Derived : public Base {};

template < typename T >
struct Foo
{
    static void f() { std::cout << "Default" << std::endl; }
};

template <>
struct Foo< Base >
{
    static void f() { std::cout << "Base" << std::endl; }
};

int main()
{
    Foo<Derived>::f(); // prints "Default"
}

(2)
#include <type_traits>
#include <iostream>

struct Base {};
struct Derived : public Base {};

template <typename T, typename Enable = void>
struct Foo
{
    static void f() { std::cout << "Default" << std::endl; }
};

template <typename T>
struct Foo<
    T, typename 
    std::enable_if< std::is_base_of< Base, T >::value >::type
>
{
    static void f() { std::cout << "Base" << std::endl; }
};

int main()
{
    Foo<Derived>::f(); // prints "Base"
}

enable_if更灵活

我认为你应该更喜欢enable_if方法:它可以实现你可能需要的一切,甚至更多。

例如。可能存在派生类可替换基类的情况,but你[不能假设/不想应用]相同的特征/专业化是有效的(例如,因为 Base 是 POD 类,而 Derived 和非 POD 行为或类似的行为与类组成完全正交)。

enable_if使您能够准确定义条件。

混合方法

您还可以通过实现一个特征类来实现一些中间立场,该特征类从通用特征派生一些特定于应用程序的特征。 “自定义”特征可以使用enable_if和元编程技术来根据需要以多态方式应用特征。这样,您的实际实现就不必重复一些复杂的enable_if/dispatch舞蹈,而可以简单地使用自定义特征类(隐藏复杂性)。

我认为一些(很多?)Boost 库使用混合方法(我已经看到它以某种方式桥接,例如 fusion/mpl,我认为 Spirit 中还有各种迭代器特征)。

我个人喜欢这种方法,因为它可以有效地将“管道”与图书馆的核心业务隔离开来,从而使维护变得容易和文档(!) 容易多了。

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

关于模板专业化和继承的良好实践 的相关文章

  • 如何知道并加载特定文件夹中的所有图像?

    我有一个应用程序 C Builder 6 0 需要知道特定文件夹中的图像总数 然后我必须加载它们 在 ImageList 或 ComboBoxEx 中 或任何其他控件中 我怎样才能做到这一点 我知道如何在控件中加载图像 或保存在 TList
  • .NET 可移植类库中的 .ToShortDateString 发生了什么

    我想知道为什么没有 ToShortDateString在 NET 可移植类库中 我有 2 个项目 Silverlight 和常规 NET 类库 使用相同的代码 并且代码涉及调用 ToShortDateString on a DateTime
  • Linq Where 本地计数器关闭在 VS watch 中的结果不同

    我尝试删除前 3 个元素array与 LinQWhere扩展功能 这是一个例子 var array new 1 2 3 4 5 6 7 8 9 var count 3 var deletedTest1 0 var test1 array W
  • 字节到二进制字符串 C# - 显示所有 8 位数字

    我想在文本框中显示一个字节 现在我正在使用 Convert ToString MyVeryOwnByte 2 但是 当字节开头有 0 时 这些 0 就会被删除 例子 MyVeryOwnByte 00001110 Texbox shows g
  • 对数字进行向上和向下舍入 C++

    我试图让我的程序分别向上和向下舍入数字 例如 如果数字是3 6 我的程序应该四舍五入最接近的数字 4 如果该数字是3 4 它将向下舍入为 3 我尝试使用ceil库获取 3 个项目的平均值 results ceil marks1 marks2
  • glDrawElements 只绘制半个四边形

    这是我的功能 void Object draw2 if mIsInitialised return Tell OpenGL about our vertex and normal data glEnableClientState GL VE
  • 如何检测斑点并将其裁剪成 png 文件?

    我一直在开发一个网络应用程序 我陷入了一个有问题的问题 我会尝试解释我想要做什么 在这里您看到第一个大图像 其中有绿色形状 我想要做的是将这些形状裁剪成不同的 png 文件 并使它们的背景透明 就像大图像下面的示例裁剪图像一样 第一张图像将
  • CMake - 将预构建库链接到 C# 项目

    我正在使用 CMake 构建 C 库 该库依赖于已构建的库 dll 我似乎无法让图书馆链接到我的图书馆 我尝试过使用target link libraries mylib external lib 我也尝试过暴力破解 reference e
  • 推送 Lua 表

    我已经创建了一个Lua表C 但我不知道如何将该表推入堆栈顶部 以便我可以将其传递给 Lua 函数 有谁知道如何做到这一点 这是我当前的代码 lua createtable state libraries size 0 int table i
  • 如何在不使用reinterpret_cast的情况下使用dlsym()加载函数?

    我正在尝试使用 clang tidy 来强制执行 C 核心指南 虽然它确实有很多有效点 但有一件事我无法真正解决 dlsym 返回一个void 我需要以某种方式将其转换为正确的函数指针 为此 我使用reinterpret cast 由于指南
  • 当格式字符串包含“{”时,String.Format 异常

    我正在使用 VSTS 2008 C Net 2 0 执行以下语句时 String Format 语句抛出 FormatException 有什么想法是错误的吗 这是获取我正在使用的 template html 的位置 我想在 templat
  • C#:如何使用 SHOpenFolderAndSelectItems [重复]

    这个问题在这里已经有答案了 有人可以举例说明如何使用 shell 函数吗SH打开文件夹并选择项目 http msdn microsoft com en us library bb762232 VS 85 aspx来自 C 我不太明白如何使用
  • 在可观察项目生成时对其进行处理

    我有一个IObservable它会生成一次性物品 并且在其生命周期内可能会生成无限数量的物品 因此 我想在每次生成新项目时处理最后一个项目 因此Using http reactivex io documentation operators
  • 使用 AutoMapper 进行 LINQ GroupBy 聚合

    试图让查询工作 但老实说不确定如何 或者是否可能 进行它 因为我尝试过的一切都不起作用 共查询6个表 Person PersonVote PersonCategory Category City FirstAdminDivision Per
  • 如何在 C++ 中使用 PI 常数

    我想在一些 C 程序中使用 PI 常数和三角函数 我得到三角函数include
  • 便携式终端

    有没有办法根据所使用的操作系统自动使用正确的 EOL 字符 我在想类似的事情std eol 我知道使用预处理器指令非常容易 但很好奇它是否已经可用 我感兴趣的是 我的应用程序中通常有一些消息 稍后我会将这些消息组合成一个字符串 并且我希望将
  • 在 MVVM 中,可以在视图后面的代码中访问 ViewModel 吗?

    在 MVVM 模式中 是否可以接受甚至可以访问视图代码后面的 ViewModel 属性 我有一个可观察的集合 它填充在 ViewModel 中 我需要在视图中使用它来绑定到带有链接列表的无限滚动条 IE private LinkedList
  • 在 unix 中编译 dhrystone 时出错

    我是使用基准测试和 makefile 的新手 我已经从下面的链接下载了 Dhrystone 基准测试 我正在尝试编译它 但我遇到了奇怪的错误 我尝试解决它 但没有成功 有人可以帮助我运行 dhrystone 基准测试吗 以下是我尝试编译的两
  • C++0x 中的新 unicode 字符

    我正在构建一个 API 它允许我获取各种编码的字符串 包括 utf8 utf16 utf32 和 wchar t 根据操作系统 可能是 utf32 或 utf16 新的 C 标准引入了新类型char16 t and char32 t没有这么
  • 当我读取 500MB FileStream 时出现 OutOfMemoryException

    我使用 Filestream 读取大文件 gt 500 MB 但出现 OutOfMemoryException 任何有关它的解决方案 我的代码是 using var fs3 new FileStream filePath2 FileMode

随机推荐

  • Web Worker 与 Promise

    为了使 Web 应用程序具有响应能力 您可以使用异步非阻塞请求 我可以设想两种方法来实现这一目标 一种是使用 deferreds promise 另一个是网络工作者 对于 Web Workers 我们最终引入了另一个流程 并且产生了来回整理
  • PHP 错误日志已停止工作。它确实起作用了

    它已经工作了很长时间并且停止了 我一定错过了一些明显的东西 File etc php5 apache2 php ini相关设置有 display errors On I am not sure if this makes a differe
  • NSUndoManager:重做不起作用

    我正在制作一个使用 NSSlider 的简单应用程序 可以使用两个按钮将其设置为最大值或最小值 撤消管理器应跟踪所有更改并允许撤消 重做使用这两个按钮所做的所有更改 这是界面 import
  • 生成一个范围内的随机偶数?

    这是我遵循的格式 int randomNum rand nextInt max min 1 min 这是我的代码 我正在尝试获取 1 到 100 之间的随机偶数 Random rand new Random int randomNum ra
  • 如果我想使用 gitignore 中的文件怎么办

    对于敏感数据 例如 aws 密钥或密码 我将它们放入 gitignore 中的文件中 以确保它不会提交到 git 但是 当脚本运行时要使用按键时 我该怎么办 运行前手动添加文件中的关键内容 如果程序需要由Jenkins定期触发怎么办 谁能帮
  • Django:操作错误没有这样的表

    我正在使用 Django CMS 的 Django 项目中构建一个相当简单的应用程序 Research 这是我对项目 应用程序的第一次尝试 它的主要目的是存储各种知识资产 即研究人员撰写的文章 书籍等 问题是当我将浏览器指向 researc
  • Visual Studio 监视中的向量“无运算符“[]”与这些操作数匹配”错误

    在 Visual Studio 2012 中单步执行以下示例代码时 std vector
  • 如何在 OpenGL 中对 glutSolidTorus 进行纹理处理? [关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我正在尝试纹理glutSolidTorus 这是我的代码 glColor3f 1 0f 1 0f 1 0f glEnab
  • UIButton 垂直对齐不起作用

    我不明白为什么在下面的代码中 标题对齐没有保持在顶部 UIButton btn2 UIButton buttonWithType UIButtonTypeRoundedRect btn2 titleLabel font UIFont sys
  • 编辑主键

    如果表只包含主键字段 是否可以在 MVC3 中编辑主键 例如 我有一个控制台表 其中我将控制台名称作为主键 我希望能够编辑它并更改它并保存编辑后的值 如果您需要更多信息 请告诉我 作为一般规则 您永远不应该编辑主键 SQL Server 中
  • Jquery:如何向 mouseleave 添加延迟,以便如果有人无意间将鼠标悬停在元素上,它仍然保持打开状态

    悬停意图插件与我需要的相反 我有一个由 trigger 触发的 popup 当我将鼠标悬停在其上时 我希望 popup 在几秒钟内不淡出 但如果我将鼠标悬停 然后再次悬停 则取消将要发生的淡出并保持 popup 打开 有谁知道我会怎么做 这
  • 反应式扩展超时不会停止序列?

    我正在尝试做一个IObservable
  • 为我的数据库 mysql 中的每一行调用 php 脚本

    如果这是一个愚蠢的问题 我很抱歉 但我现在不知道如何为表中的每一行调用 php 脚本 我正在使用mysql 我以后会使用PDO 我知道它更好 这是我的 选择 页面 我在其中选择所需的行
  • Printer_open() 打印 html 输出

    With printer open php 中的函数 我可以打印我保存的字符串 content变量 并且能够从文件打印 printer Pserver php net printername handler printer open pri
  • 插入缺失的日期行并在新行中插入旧值 PySpark

    我有一个 DataFrame 其中包含一个人 一个体重和时间戳 如下所示 person timestamp weight 1 2019 12 02 14 54 17 49 94 1 2019 12 03 08 58 39 50 49 1 2
  • 如何在 ASP.net 控制器操作中访问整个查询字符串

    我知道如果我有一个像 XController Action id 1 这样的 url 和一个操作方法 void Action int id id 参数将自动从查询字符串中读取 但是 当我事先不知道所有参数的名称时 如何访问整个查询字符串 例
  • 哪个版本的 Xcode 支持 iOS 12.2?

    当我在运行 iOS 12 2 的 iPhone 7 上运行我自己开发的软件时 弹出了一个警报 这款 iPhone 7 型号 1660 1778 1779 1780 运行的是 iOS 12 2 16E5201e 此版本的 Xcode 可能不支
  • SQL Server 用最后一个值替换 NULL [重复]

    这个问题在这里已经有答案了 我想找到一种方法用最后一个非 NULL 值替换 NULL 值 我有一张像这样的桌子 Date Cost 2017 01 01 18 6046511 2017 01 03 22 9787234 2017 01 03
  • oracle 限制为 1000 / hibernate

    Oracle 知道 1000 个元素的限制where a in 条款 当 Hibernate 与 Oracle 结合使用时 是否也存在此限制 Hibernate 中仍然存在此数据库限制 如果您确实需要在 in 子句中包含超过 1000 个项
  • 关于模板专业化和继承的良好实践

    模板专业化不考虑继承层次结构 例如 如果我专门设计一个模板Base并实例化它Derived 不会选择专业 参见下面的代码 1 这可能是一个主要障碍 因为它有时会导致违反里氏替换原则 例如 在工作时这个问题 https stackoverfl