根据调用方/上下文专门化函数的行为
Specializing a function's behavior depending on caller/context
假设您有一个程序,其中两段旧代码执行相同的工作,只是它们在两个不同的上下文中执行:一个在GUI中执行,另一个在API中执行。假设你想重构它们以便池化/合并代码,这样你只有一个代码为API和;GUI。
但是有一个问题:代码片段并不是100%相同。与API相比,GUI必须做一些额外的工作(例如,在GUI中,所做的每个更改都必须通过撤消/重做系统,但在API中没有,因为它不使用撤消/重做)。
所以说你可以合并80%的代码行为,但是你剩下的20%必须专门用于API和GUI(即。
你怎么解决这个问题?
我想到了:
- 创建一个公共函数,其中通过回调注入专门的代码(例如;子);
- 或:创建一个模板化的公共函数,调用其他模板化的子函数。由于这些子函数也是模板化的,因此它们可以具有模板专门化,一种专门化用于GUI;API。通用模板化函数的参数化将确保调用正确的子函数的模板专门化。
但这些解决方案都不满足我:
-
给一个函数传递几个回调函数真的会让它的签名很快变得混乱;
-
第二种解决方案,当你开始模板化时,你可能最终会模板化大部分涉及的函数(这当然取决于你的代码,但在我的情况下,这是一个问题)。
还有其他想法吗?
听起来唯一的区别是GUI做了API没有做的事情。如果API做了一些GUI没有做的事情,那就会影响答案。
,
如果有任何方法重构你的代码,使所有的特殊情况的东西发生在同一个代码块,你可以把代码块放在一个函数的GUI,然后调用"通用"函数后。
void GUI_Func()
{
//do some special GUI stuff
common_func();
}
void common_func()
{
//do stuff common to both the GUI and the API
}
,
然而,在我看来,你似乎有必要在整个函数中分散不同的功能。
你提到了撤消/重做系统。这些代码可以移动到一个负责处理撤销和重做的类中吗?在这种情况下,您可以在template<typename UndoRedo>
上模板函数。对于GUI表单,你将在你的Undo/Redo类中传递,对于API表单,你将在一个带有匹配接口的空类中传递;尽管没有任何功能。在编译时,空类操作将是无操作的,并且可能被编译器忽略。
我不确定我理解你的代码复杂到什么程度,但对于某些情况,比如这些,我会传递一个可选的布尔参数,当它为真时,会使额外的东西发生。同样,我不完全确定这是否适合这种情况。在这种情况下,GUI将调用参数设置为true
的公共函数,API版本将调用参数设置为false
的公共函数。
在你的地方,我会考虑委托,你把所有与UI相关的代码放在这个委托类中
- 尝试根据类中 typedef 的存在来专门化模板函数
- 如何基于模板化类的基类专门化成员函数
- 专门化模板覆盖函数/避免对象切片
- 如何使用模板化类专门化模板化函数?
- 线程 std::调用未知类型,无法专门化函数错误
- 如何在编译时专门化大型模板函数中的小部分
- 模板函数,其中一个参数需要专门化,而另一个不需要
- 错误 C2893 无法专门化函数模板'unknown-type std::invoke(_Callable &&,_Types &&...)'
- 从 std 命名空间中专门化函数模板的想法有多糟糕?
- 为模板函数专门化一个模板类
- 基于参数值的c++模板成员函数专门化
- 如何确定函数专门化的主模板
- 等价参数的c++函数专门化
- 基于运行时值调用不同的模板函数专门化
- 跨库的模板函数专门化符号匹配
- 模板函数专门化,c++
- 如何使用type_traits或模板函数专门化来整合模板方法
- 如何在子类中重载模板化函数(专门化)
- 可变模板函数:专门化头/尾和空基准情况
- 不允许void的部分函数专门化-替代解决方案