问题标签 [crtp]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
9 回答
685 浏览

c++ - 即时推导

有一个不太常见的 C++ 习惯用法,过去我用过几次效果很好。我似乎不记得它是否有一个常用的名称来描述它。

它与mixinsCRTPtype-erasure有点相关,但与这些东西无关。

当您想向一个类添加一些实现,但又不想将它放在该类或它派生的任何类中时,就会发现问题。造成这种情况的一个原因可能是该类可能是继承层次结构的一部分,其中实现应该只发生一次。

暂时不考虑诸如层次结构是否应该具有具体的非叶类,或者在某些情况下是否可以选择虚拟继承等问题,我知道一种解决方案是在派生自的模板类中提供实现它的模板参数。然后,这允许您在创建实例时使用模板,但只能通过指针或对其基之一的引用来使用该对象(从广义上讲,这就是类型擦除的来源)。

一个例子可能是你有一个侵入性的引用计数。您的所有类都派生自 ref count 接口,但您只希望 ref count 本身和 ref count 方法的实现出现一次,因此您将它们放在派生模板中 - 我们称之为ImplementsRC<T>。现在您可以像这样创建一个实例:

我正在掩盖诸如由多个模板化重载形成的转发构造函数等内容。

所以,希望我已经说清楚了这个成语是什么。现在回到我的问题 - 这个成语是否有一个公认的或至少普遍使用的名称?

0 投票
5 回答
1012 浏览

c++ - 对派生类构造函数的依赖问题

我正在研究一个遗留框架。假设“A”是基类,“B”是派生类。这两个类都进行了一些关键的框架初始化。FWIW,它大量使用ACE库。

我有一种情况;创建了一个“B”的实例。但是'A'的ctor依赖于一些只能从'B'执行的初始化。

正如我们所知,当“B”被实例化时,“A”的 ctor 在“B”之前被调用。该virtual机制不适用于ctors,使用static functions被排除(由于static-initialization-order-fiasco)。

我考虑使用 CRTP 模式如下:-

但是在初始化器列表中初始化的类成员具有未定义的值,因为它们尚未执行(在上述情况下为 fe 'a')。在我的例子中,有许多这样的基于框架的初始化变量。

是否有任何众所周知的模式来处理这种情况?

提前致谢,


更新

基于 dribeas 给出的想法,我想出了一个临时解决方案来解决这个问题(一个成熟的重构目前不适合我的时间表)。以下代码将演示相同的内容:-

有关相同内容的更多讨论,请参见clc++.m上的此链接。Konstantin Oznobikhin 给出了一个很好的通用解决方案。

0 投票
1 回答
753 浏览

c++ - CRTP 的 C++ 编译器错误

我有以下类层次结构:

Comeu 和 Intel C++ v11 声称一切都很好,但是 GCC (4.4.1) 和 VC++ 2008 似乎抱怨 ( http://codepad.org/KQPDsqSp ),例如:

我相信代码的格式是正确的,但是我可能是错的,我希望 SO C++ 社区的某个人可以对这个问题提供一些见解。

注意:在 class_b 中的 using 指令之前添加“public”,解决了 gcc 和 VS 的问题。应用 using 指令的类的访问器部分是否应该覆盖基类的派生模式(公共、私有)?

简而言之就是这个

  • 编译器错误 - 如果是 GCC、VS 或 Comeu、Intel 哪个编译器
  • 上面的代码格式正确吗?
  • 调用 using 指令的访问器部分是否覆盖了基类的派生模式?
0 投票
3 回答
668 浏览

c++ - CRTP 继承

我有这3节课。

而且,我这样做:

它打印:“在 C 中”。

如果我这样做,

它再次打印“In C”

到底是怎么回事?

0 投票
1 回答
2725 浏览

g++ - C++ 中的 Mixin、可变参数模板和 CRTP

这是场景:我想要一个可以有可变数量的 mixin 的主机类(使用可变参数模板不太难——例如参见http://citeseerx.ist.psu.edu/viewdoc/summary?doi =10.1.1.103.144)。但是,我还希望由宿主类对 mixin 进行参数化,以便它们可以引用其公共类型(使用 CRTP 习惯用法)。尝试混合两者时会出现问题——我不清楚正确的语法。例如,以下代码使用 g++ 4.4.1 编译失败:

出现错误:

有没有人有将可变参数模板与 CRTP 混合的成功经验?

0 投票
1 回答
2186 浏览

c++ - 在 C++ 中将基于策略的设计与 CRTP 混合

我正在尝试编写一个基于策略的主机类(即,从其模板类继承的类),其中策略类也由主机类模板化,以便它可以访问其类型。这可能有用的一个示例是,策略(实际上像 mixin 一样使用)使用多态 clone() 方法扩充主机类。这是我正在尝试做的一个最小示例:

不幸的是,这无法编译,在我看来像是循环类型依赖:

如果有人能发现一个明显的错误,或者成功地将 CRTP 混合到策略中,我将不胜感激。

0 投票
2 回答
3671 浏览

java - 创建循环通用引用

我正在编写一个应用程序来在对等网络中进行一些分布式计算。在定义网络时,我有两类 P2PNetwork 和 P2PClient。我希望这些是通用的,因此具有以下定义:

使用 P2PClient 定义 setNetwork(T network) 的方法。我希望用这段代码描述的是:

  1. P2PNetwork 由某种类型的客户端组成
  2. P2PClient 只能属于其客户端与该客户端(循环引用)相同类型的网络

这对我来说似乎是正确的,但如果我尝试创建一个非通用版本,例如

和其他变体我从编译器收到许多错误。所以我的问题如下:

  1. 通用循环引用是否可能(我从未见过任何明确禁止它的东西)?
  2. 上述通用定义是对这种循环关系的正确定义吗?
  3. 如果它是有效的,它是否是描述这种关系的“正确”方式(即是否有另一个有效的定义,在风格上是首选的)?
  4. 给定正确的通用定义,我将如何正确定义客户端和服务器的非通用实例?
0 投票
3 回答
2390 浏览

c++ - 如何编写具有超过 2 层继承的奇怪重复模板?

我在 Curiously Recurring Template Pattern 上读过的所有材料似乎都是一层继承,即BaseDerived : Base<Derived>. 如果我想更进一步怎么办?

如何重写此代码以编译而不会出现错误并显示


_

使用 c.get().print() 和 b.get().print() 吗?

动机:假设我有三个班级,

每个类在其构造函数中接受 6 个左右的参数,其中许多是可选的并且具有合理的默认值。为了避免可选参数的乏味,最好的解决方案是使用命名参数惯用语

这个习惯用法的一个基本问题是参数类的函数必须返回它们被调用的对象,但是一些参数被提供给 GuiElement,一些给 Window,还有一些给 AlertBox。你需要一种方法来写这个:

然而这可能会失败,因为例如 GuiElementParameter(int) 可能返回 GuiElementOptions&,它没有 WindowParameter(int) 函数。

以前有人过这个问题,解决方案似乎是某种奇怪的重复模板模式。我使用的特殊口味是here

不过,每次我创建一个新的 Gui 元素时都要编写很多代码。我一直在寻找简化它的方法。复杂性的一个主要原因是我使用 CRTP 来解决 Named-Parameter-Idiom 问题,但我有三层而不是两层(GuiElement、Window 和 AlertBox),并且我当前的解决方法是我拥有的类数量的四倍. (!) 例如,Window、WindowOptions、WindowBuilderT 和 WindowBuilder。

这让我想到了我的问题,我本质上是在寻找一种更优雅的方式来在长继承链上使用 CRTP,例如 GuiElement、Window 和 Alertbox。

0 投票
2 回答
863 浏览

c++ - C++ CRTP(模板模式)问题

以下代码无法编译,问题在于T::rank父模板中不可访问(我认为)或未初始化。

你能告诉我具体是什么问题吗?明确地通过排名是唯一的方法吗?或者有没有办法直接查询张量类?

谢谢

我知道解决方法,但是对用于自学的模板实例化机制感兴趣

0 投票
2 回答
2899 浏览

c++ - CRTP 中的模板派生类(Curiously Recurring Template Pattern)

我使用了不能用 g++ 4.2.1 编译的 CRTP,可能是因为派生类本身就是一个模板?有谁知道为什么这不起作用,或者更好的是,如何使它起作用?示例代码和编译器错误如下。

资料来源:foo.C

编译器错误