c++ - 在基于策略的重构中缩短模板参数

标签 c++ templates c++11 c++14 policy

我正在尝试使用策略重构一些代码(参见 Modern C++ Design 一书)并希望缩短或简化宿主类方法的代码。假设我有一个名为 Hostclass 的已经实现的类:

// Hostclass header, start version
struct Hostclass {
    void Hostfct1();
    void Hostfct2();
    ...
};
// method definitions, start version
void
Hostclass::Hostfct1(){...}

void
Hostclass::Hostfct2(){...}
...

现在我有一个策略类

struct Policy1class {
    void Policy1fct(){};
};

并希望将 Policy1class 注入(inject)到 Hostclass 中。这意味着我必须更改 Hostclass 的 header :

// Hostclass header, second version
template <typename Policy1>
struct Hostclass : public Policy1 {

但是方法呢? Hostclass 现在是一个模板类,所以函数定义需要另一个说明符:

// method definitions, second version
template <typename Policy1>
void
Hostclass<Policy1>::Hostfct() {...}
...

现在我想用另一个策略进一步丰富Hostclass

struct Policy2class {
    void Policy2fct(){};
};

所以我必须再次更改标题:

// Hostclass header, third version
template <typename Policy1, typename Policy2>
struct Hostclass : public Policy1, Policy2 {

以及说明符:

// method definitions, third version
template <typename Policy1, typename Policy2>
void
Hostclass<Policy1,Policy2>::Hostfct() {...}
...

我认为每次新策略进入阶段时更改所有主机类方法的所有说明符有点麻烦是否有可能,或许使用 C++14 的新工具及其模板别名或extern template简化此方法定义?我有这样的东西

// invalid code
class P1;
class P2;
using H = Hostclass<P1,P2>;
// method definitions, dream version
void
H::Hostfct1() {...}

void
H::Hostfct2() {...}
...

记在心里。我能想到的绕过定义规范的唯一其他选择是实现一个 HostclassWrapper 类,它继承自 Hostclass 和所有其他策略:

// Hostclass header, start version
struct Hostclass {...};
// method definitions, start version
void
Hostclass::Hostfct1(){...}
// new wrapper class
template <typename Policy1, typename Policy2>
class HostclassWrapper : public Hostclass, Policy1, Policy2 {
};

还有什么建议吗?

最佳答案

您可以简单地使用可变参数模板:

template <class... Policies>
class Host : public Policies... { ... }

template <class... Policies>
void Host<Policies...>::func() { ... }

避免在每个成员函数定义中重复模板声明的唯一方法是在类定义本身中定义它们。

但如果您支持任意数量的策略,可变参数模板绝对是您想要的。

关于c++ - 在基于策略的重构中缩短模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36011393/

相关文章:

c++ - 混淆返回引用

c++ - 使用输入和输出选项读取文件流后无法写入

grails - 在Grails中渲染HTML文件

C++ 数组大小声明和常量

c++ - 在异常消息中使用 constexpr

c++ - 来自类数组的奇怪行为

c++ - 将 1 到 100 之间的数字相加 OpenMP

c++ - 指向模板函数的空指针

c++ - 为什么我的重载转换运算符无法访问私有(private)成员?

c++ - 面试位: Giving run time error on submit but correct output on custom test case