gpt4 book ai didi

c++ - CRTP 的运行时多态性设计和策略

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:55:11 26 4
gpt4 key购买 nike

在我的工作中,我有很多内部函数调用的循环;性能在这里很关键,虚函数调用的开销是 Not Acceptable ,所以我尝试通过使用 CRTP 来避免动态多态性,如下所示:

template<class DType>
struct BType {
DType& impl(){ return *static_cast<DType*>(this); }
void Func(){ impl().Func(); }
};

struct MyType : public BType<MyType> {
void Func(){ /* do work */ }
};

template<class DType>
void WorkLoop(BType<DType>* func){
for (int i=0;i<ni;++i){ func->func(); }
}

struct Worker {
void DoWork(){ WorkLoop(&thing) };
private:
MyType thing;
};

Worker worker;
worker.DoWork();

旁白:实际使用 CRTP 类的正确方法是什么?现在我需要实际类型取决于运行时用户选项,通常动态多态性与抽象基类/策略模式会是正确的设计,但我负担不起虚函数调用。一种方法似乎是使用一些分支:

struct Worker {
void DoWork(){
if (option=="optionA"){
TypeA thing;
WorkLoop(thing); }
else if (option=="optionB"){
TypeB thing;
WorkLoop(thing); }
...

但这似乎是一个糟糕的设计。在此处将其作为模板参数传递(或使用基于策略的设计)似乎是一种选择:

template<class T>
struct Worker {
void DoWork(){ WorkLoop(&thing) };
T thing;
};
if (option=="optionA"){
Worker<TypeA> worker; worker.DoWork() } ...

但是这里的 worker 只在 if 分支中有范围,我需要它在程序的长度内有一个生命周期。此外,相关的用户选项可能会指定 4 个以上的“策略”,每个策略都有多个选项(比如 4 个),所以看起来你很快就会遇到一个讨厌的问题,模板类可能需要 4*4* 中的 1 个4*4模板组合。

此外,将循环逻辑移动到类型中不是一个选项 - 如果它是虚函数调用开销可以忽略不计,我会使用正常的多态性。循环的实际控制可能相当复杂,并且会在运行时发生变化。

这是否建议我尝试构建自定义迭代器并将其作为函数参数传递并使用正常的多态性,或者这会产生类似的开销吗?

在运行时选择类而不求助于指向抽象基类的指针的好的设计是什么?

最佳答案

您有一个运行时到编译时分派(dispatch)的经典问题:“此外,相关的用户选项可能会指定额外的策略,每个策略都有几个选项”。您的代码必须支持许多您在编译时不知道的选项组合。

这意味着您必须为每种可能的组合编写一些代码,然后将用户的选择分配给其中一种组合。这意味着您必须使用一些丑陋且效率不高的代码来解析用户的运行时决策并将它们分派(dispatch)到预定义的模板中。

为了保持尽可能高的效率,您希望在尽可能靠近入口点的非常高的级别执行此调度。另一方面,您可以根据需要对低级代码进行模板化。

这意味着从非模板代码到混合模板和选项再到完全模板化,dispatch 可以有几个向下的步骤。

通常使用标签和策略可以更好地实现它,而不是 CRTP,但这与您的算法和选项密切相关。

关于c++ - CRTP 的运行时多态性设计和策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20713048/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com