问题标签 [static-polymorphism]
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.
c++ - 如果使用 CRTP,派生类方法是否会覆盖该方法的基类版本?
几天前,我发现了一个有趣的 C++ 结构,名为Curiously Recurring Template Pattern(通常缩写为 CRTP)。从那时起,我一直试图完全理解这个技巧是如何工作的。
假设我有以下代码片段
CRTP 背后的所有“魔力”显然都在行static_cast<T*>(this)->draw()
。但它是如何详细工作的?我的理解如下。假设我有Circle c
.
如果编译器看到这个声明,这是他GraphicalObject
用参数实例化模板的信号Circle
。我认为这会导致GraphicalObject<Circle>
编译器创建结构
draw
因此创建了具有该方法的特殊版本的 struct 。该结构GraphicalObject<Circle>
构成该结构的基础Circle
结构。
在第二步中创建结构的实例c
,即调用隐式构造函数。由于首先调用的是从该结构的隐式构造函数继承的事实。在我看来,这会导致创建对象内部的实例。这样对吗?然后我认为struct中声明的方法覆盖了struct中声明的方法。但这对我来说没有意义。我宁愿期望来自 的方法的“专业”版本不会被覆盖。请你能告诉我我对 CRTP 工作原理的理解有什么问题吗?Circle
Circle
Circle
GraphicalObject<Circle>
GraphicalObject<Circle>
c
draw
Circle
draw
GraphicalObject<Circle>
draw
GraphicalObject<Circle>
c++ - 使用 std::variant 的静态多态性
我正在尝试使用 std::variant 实现类似静态多态的东西。我想声明使用 VARIANT_METHOD 或 VARIANT_METHOD_CONST 的方法,这些方法应该采用返回类型、方法名称、参数和限定符。
我不能声明两个具有相同名称但具有不同参数的方法。我想写这样的东西:
c++ - 在模板类中使用 std::conditional 的问题
我正在尝试使用非类型模板参数定义模板类。然后我使用这个模板参数确定这个类的成员的类型std::conditional
。我遇到了一些编译时错误。
下面是MWE。在这个 MWE 中,我试图根据条件分别为真(结构化)或假(非结构化)来制作FiniteElementList
模板类的成员 。类 ,包含一些成员和友元函数,这些函数只是暂时声明的,可能会在稍后阶段定义。Mesh
std::vector
std::list
Mesh
MWE
汇编:
我正在尝试使用 clang 编译器进行如下编译
c++ -O3 -Wall -Wextra -Wpedantic -std=c++17 mesh_structure.cpp -o mesh_structure
我遇到了以下错误
奇怪的是,如果我Mesh<StructuredUnstructured::kStructured> structured;
从main()
函数中删除第二行,代码就会编译。我不太明白这里出了什么问题。任何帮助将不胜感激。
谢谢你。
class - 使用模板将多态类重写为一个类(编译时多态)
在我当前的代码中,我使用运行时多态性从 LightBase 类创建不同的“光”子类型。然而,lighttypes 在编译时是已知的(预处理器选择正确的变体)。所以我认为它确实不是正确的工具,因为它很慢(虚拟 getter 函数的 vtable 查找)并且可以在编译时完成。我只是不知道如何...可以用模板完成吗?我在模板编程方面没有太多经验,所以我不知道有什么可能。
本质上,我想实例化一个 NormalLight 或 SpecialLight 类型的子类,它们具有与 LightBase 相同的功能,但对一组不同的常量进行操作:
在一个函数中,我可以有条件地检查模板参数(我猜),但它是一个类定义。此外,这个东西应该在 C++11 中编译。有任何想法吗?
c++ - 是否可以在没有动态多态性的情况下在 C++ 中实现状态设计模式?
假设我有以下 C++ 代码
假设我想根据一些外部事件在运行时algorithm_A
和运行时之间切换algorithm_B
(基本上我将实现状态设计模式)。所以algorithm
指针指向algorithm_A
或algorithm_B
对象。我的问题是是否有任何方法可以实现在运行时动态切换算法的能力,而无需公共接口中的虚拟方法,例如奇怪的重复模板模式?
c++ - C++17 std::variant 比动态多态性慢?
我正在关注这个博客,并试图将动态多态性代码替换为使用std::variant
and std::visit
。但我无法让std::variant
+std::visit
比虚拟结构 impl 更好地工作。它慢了大约1.3-1.5 倍!(GCC 10.3 -O3 C++17)
用例如下。假设我们正在比较两个表的第 i 行和第 j 行。表可能具有异构类型的列。假设我们可以访问列缓冲区。我正在做的是测试,
对于动态多态性,我有以下int
和float
这被转换为std::variant
+std::visit
如下。
我在这里进行了基准测试 https://quick-bench.com/q/u-cBjg4hyQjOs6fKem9XSdW7LMs
有人可以解释为什么这个std::variant
+std::visit
选项比动态多态方法慢吗?我期待否则!我的方法和/或基准有问题吗?
c++ - 编译时接口(非虚拟)
如果你想为同一个对象有不同的公共接口,你可以使用虚拟基类。但是那些有开销(内存和空间)。
可以将对象转换为具有不同访问修饰符和相同大小的类。这通常在纯 C 中完成,并带有隐藏实现细节的结构。但是这个解决方案本质上是不安全和未定义的行为,可能很难找到错误,因为优化器如果完成了它的工作,可能无法很好地处理禁止的别名(相同的内存位置具有不同的名称)。当访问修饰符不同时,一些编译器可能会重新排列内存布局。像 dynamic_cast<>、reinterpret_cast<> 和 bit_cast<> 这样的强制转换只允许用于某些类。
现在我找到了至少一种解决方案,哪种使用超类而不是基类作为接口,并且似乎是合法的。这是真的?有没有更简单的方法可以到达那里?
复杂的.h:
视图1.h:
视图2.h:
视图3.h:
组合.h:
测试.cpp:
输出是:
视图只能看到它们各自的成员变量(其他成员受保护)。允许从 Combine 转换为基类(3 个视图)。Complex 类没有特殊要求,甚至没有标准布局或默认可构造。
Complex 类包含所有成员和实现,但必须构造 Combined 类,以便所有视图都是静态基类。
在显示的示例中,视图只能从具有 view1/2/3() 函数的类内部创建,因为继承受到保护。可以进行公共继承,但必须显式地使所有成员对受保护的视图不可见。并且可以看到视图的链接顺序。但优点是,可以直接从组合类中转换视图。这也许也可以通过运算符 View1& 转换运算符来实现?
由于视图知道对象的实际构造(动态)类(=Combined),因此可以从视图指针中进行破坏(此处未实现)。
这些视图仅适用于编译时已知的对象类,否则需要使用传统的虚拟解决方案。
对于静态(非开销)视图,是否有一种更简单(合法)的方式,使用起来很舒服?
(人们总是可以回退到朋友功能)