我有三个可以静态组合的类。最低级别的类是A
,是一个带有单个参数的模板类。这可能是一个int。然后我有一个更高级别的课程B
,这取决于类型T
和A
。最后,我有一个更高级别的C
,它依赖于T
,A
和B
。
我可以看到两种方法来编码这些关系,使用模板模板或公共范围的typedef:
// template-template style:
template <typename T>
struct A {
T at_;
};
template <typename T,
template <typename> class A>
struct B {
A<T> ba_;
T bt_;
};
template <typename T,
template <typename> class A,
template <typename, template <typename> class> class B>
struct C {
B<T, A> cb_;
A<T> ca_;
T ct_;
};
// public-scoped typedef style:
template <typename T>
struct A2 {
typedef T TType;
T at_;
};
template <class A>
struct B2 {
typedef A AType;
AType ba_;
typename A::TType bt_;
};
template <class B>
struct C2 {
typedef B BType;
B cb_;
typename B::AType ca_;
typename B::AType::TType ct_;
};
// ...
// client code:
A<int> MyA;
B<int, A> MyB;
C<int, A, B> MyC;
A2<int> myA2;
B2<A2<int> > myB2;
C2<B2<A2<int> > > myC2;
现在考虑扩展模式的新类D - 使用第一种方法,模板声明几乎完全无法管理:
// horrendous to define:
template <typename T,
template <typename> class A,
template <typename,
template <typename> class> class B,
template <typename,
template <typename> class,
template <typename, template <typename> class> class> class C>
struct D {
C<T, A, B> dc_;
B<T, A> db_;
A<T> da_;
T dt_;
};
// but nice to instantiate:
D<int, A, B, C> MyD;
第一种方法的优点是每个参与的课程都不需要为更高级别的课程做出规定。他们不需要意识到他们是层次结构的一部分,因此可以重用现有的类而不改变它们。这在理论上是可扩展的,但是如果不采用可怕的预处理器宏,类声明语法很快就会变得无法处理。
可替换地:
template <class C>
struct D2 {
typedef C CType; // <-- not required right now, but better put it in just-in-case...
C dc_;
typename C::BType db_;
typename C::BType::AType da_;
typename C::BType::AType::TType ct_;
};
第二种方法更简洁,但要求层次结构的参与者将其模板参数作为公共typedef类型提供。他们需要在此编译时接口进行协作,以便他们可以将较低级别的类型传达到更高级别。如果它们在以后成为这种层次结构的一部分,则需要进行广泛的更改。这似乎意味着最好将所有模板类中的所有模板参数作为公共范围的typedef 提供,以防万一最终被用在这种层次结构中。这对我来说并不具备可扩展性,但我在标准库中看到了类似的内容,通常会提供模板参数value_type
。
我的问题是 - 我错过了每种方法的其他优点/缺点,哪种方法在创建增长类的库时可能最有效,这些类往往是静态组合的?一种风格比另一种更被广泛接受吗?是否有其他选择?
关于实际应用的说明 - 我已经有了这个实际应用,它涉及以某种方式表现的特殊类型的数值。这些值包含在更高级别的类中,每个类都提供一层额外的功能 - 每层一个。例如,一层提供回调机制,另一层提供缓存,另一层提供值验证,另一层提供转换功能。较高层可能需要比直接在下面的层更多地了解,因此需要知道用于构成较低类型的类型。每个级别都有几种不同的实现,因此需要指定这么多类型。此层次结构的各个部分可以在其他代码中使用,反过来,该代码也可能发现自己也是层次结构的一部分。它是一个相当经典的组合&#34;通过编写较低级别的类来构建功能的模型,但是静态创建。