在基于策略的重构中缩短模板参数
Shortening template arguments in policy based refactoring
我正在尝试使用策略重构一些代码(参见书籍 Modern C++ Design)并希望缩短或简化宿主 classes 方法的代码。假设我已经实现了一个名为 Hostclass
:
的 class
// Hostclass header, start version
struct Hostclass {
void Hostfct1();
void Hostfct2();
...
};
// method definitions, start version
void
Hostclass::Hostfct1(){...}
void
Hostclass::Hostfct2(){...}
...
现在我有一个政策class
struct Policy1class {
void Policy1fct(){};
};
并想将 Policy1class
注入 Hostclass
。这意味着我必须更改 Hostclass
的 Header:
// Hostclass header, second version
template <typename Policy1>
struct Hostclass : public Policy1 {
但是方法呢? Hostclass
现在是模板 class,因此函数定义需要另一个说明符:
// method definitions, second version
template <typename Policy1>
void
Hostclass<Policy1>::Hostfct() {...}
...
现在我想用另一个策略Hostclass
进一步丰富
struct Policy2class {
void Policy2fct(){};
};
所以我必须再次更改 header:
// 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() {...}
...
我认为每次新策略进入阶段时更改所有主机class 方法的所有说明符有点麻烦。 是否有可能,也许使用 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
class 继承自 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() { ... }
避免在每个成员函数定义中重复模板声明的唯一方法是将它们全部定义在 class 定义本身中。
但是,如果您支持任意数量的策略,可变参数模板绝对是您想要的。
我正在尝试使用策略重构一些代码(参见书籍 Modern C++ Design)并希望缩短或简化宿主 classes 方法的代码。假设我已经实现了一个名为 Hostclass
:
// Hostclass header, start version
struct Hostclass {
void Hostfct1();
void Hostfct2();
...
};
// method definitions, start version
void
Hostclass::Hostfct1(){...}
void
Hostclass::Hostfct2(){...}
...
现在我有一个政策class
struct Policy1class {
void Policy1fct(){};
};
并想将 Policy1class
注入 Hostclass
。这意味着我必须更改 Hostclass
的 Header:
// Hostclass header, second version
template <typename Policy1>
struct Hostclass : public Policy1 {
但是方法呢? Hostclass
现在是模板 class,因此函数定义需要另一个说明符:
// method definitions, second version
template <typename Policy1>
void
Hostclass<Policy1>::Hostfct() {...}
...
现在我想用另一个策略Hostclass
进一步丰富
struct Policy2class {
void Policy2fct(){};
};
所以我必须再次更改 header:
// 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() {...}
...
我认为每次新策略进入阶段时更改所有主机class 方法的所有说明符有点麻烦。 是否有可能,也许使用 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
class 继承自 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() { ... }
避免在每个成员函数定义中重复模板声明的唯一方法是将它们全部定义在 class 定义本身中。
但是,如果您支持任意数量的策略,可变参数模板绝对是您想要的。