很难为这个问题想出一个好的标题。我真正需要的是能够提供具有不同数量参数的模板参数来代替单个参数。没有多大意义,所以我将讨论原因:
template < typename T, template <typename,typename> class Policy = default_policy >
struct policy_based : Policy<T, policy_based<T,Policy> >
{
// inherits R Policy::fun(arg0, arg1, arg2,...,argn)
};
// normal use:
policy_base<type_a> instance;
// abnormal use:
template < typename PolicyBased > // No T since T is always the same when you use this
struct custom_policy {};
policy_base<type_b,custom_policy> instance;
问题是,对于许多异常使用,Policy 将基于一个单一的类型 T,并且不能真正在 T 上进行参数化,因此将 T 作为参数是没有意义的。对于其他用途,包括默认用途,策略可以与任何 T 一起使用。
我有几个想法,但没有一个是真正的最爱。我认为我有一个更好的答案——使用组合而不是策略——但后来我意识到我有这种情况,其中 fun() 实际上需要类本身没有的额外信息。
这就像我第三次重构这个愚蠢的结构,并且我有很多自定义版本,我正试图整合它们。这次我想确定一些东西,而不是四处寻找,希望这次能奏效。所以我现在只是在寻找想法,希望有人有让我印象深刻的东西,我会转换神。有人有好主意吗?
编辑:您可能会问自己,为什么我不只是从基于 default_policy 模板的策略定义中检索 T。原因是 default_policy 实际上是专门针对某些类型 T 的。自从提出问题以来,我提出了一些可能是我需要的东西,这将随之而来,但我仍然可以使用其他一些想法。
template < typename T >
struct default_policy;
template < typename T, template < typename > class Policy = default_policy >
struct test : Policy<test<T,Policy>>
{};
template < typename T >
struct default_policy< test<T, default_policy> >
{
void f() {}
};
template < >
struct default_policy< test<int, default_policy> >
{
void f(int) {}
};
编辑:仍在搞砸它。我不太喜欢上面的方法,因为它使 default_policy 与“test”永久结合,因此不能在其他方法中重用,例如下面建议的多个模板。它也根本无法扩展,并且至少与“测试”一样需要一个参数列表。尝试了几种不同的方法,但都失败了,直到我找到了另一种到目前为止似乎有效的方法:
template < typename T >
struct default_policy;
template < typename T, template < typename > class Policy = default_policy >
struct test : Policy<test<T,Policy>>
{};
template < typename PolicyBased >
struct fetch_t;
template < typename PolicyBased, typename T > struct default_policy_base;
template < typename PolicyBased >
struct default_policy : default_policy_base<PolicyBased, typename fetch_t<PolicyBased>::type> {};
template < typename T, template < typename > class Policy >
struct fetch_t< test<T,Policy> > { typedef T type; };
template < typename PolicyBased, typename T >
struct default_policy_base
{
void f() {}
};
template < typename PolicyBased >
struct default_policy_base<PolicyBased,int>
{
void f(int) {}
};