c++-命名的模板参数

场景如下
template<
typename PolicySetter1 = DefaultPolicyArgs,
typename PolicySetter2 = DefaultPolicyArgs,
typename PolicySetter3 = DefaultPolicyArgs,
typename PolicySetter4 = DefaultPolicyArgs>
class BreadSlicer;
它四个参数,且都有默认值
如果我们想修改 PolicySetter4的值, 我们不得不这么做
BreadSlicer<DefaultPolicyArgs, DefaultPolicyArgs, DefaultPolicyArgs, NewPolicyArgs>
就是重复前面的每一个默认值,然后设置新值,那么有没有一种方式能让我们直接修改值而不用管前面的默认参数呢

下面带来这种技巧

#include <iostream>
#include <vector>
#include <memory>
#include <boost/type_index.hpp>

using namespace std;

class A {
 public:
    static void doSomething() {
        cout << "A::doSomething" << endl;
    }
};

class B {
 public:
    static void doSomething() {
        cout << "B::doSomething" << endl;
    }
};

class C {
 public:
    static void doSomething() {
        cout << "C::doSomething" << endl;
    }
};

class D {
 public:
    static void doSomething() {
        cout << "D::doSomething" << endl;
    }
};

class AA {
 public:
    static void doSomething() {
        cout << "**************************** AA::doSomething" << endl;
    }
};

class BB {
 public:
    static void doSomething() {
        cout << "**************************** BB::doSomething" << endl;
    }
};

class CC {
 public:
    static void doSomething() {
        cout << "**************************** CC::doSomething" << endl;
    }
};

class DefaultPolicies {
 public:
    using P1 = A;
    using P2 = B;
    using P3 = C;
    using P4 = D;
};

template<typename Policy>
class PolicySetter1 : virtual public DefaultPolicies {
 public:
    using P1 = Policy;
};

template<typename Policy>
class PolicySetter2 : virtual public DefaultPolicies {
 public:
    using P2 = Policy;
};

template<typename Policy>
class PolicySetter3 : virtual public DefaultPolicies {
 public:
    using P3 = Policy;
};

template<typename Policy>
class PolicySetter4 : virtual public DefaultPolicies {
 public:
    using P4 = Policy;
};

template<typename Base, int D>
class Discriminator : public Base {
};

template<typename Setter1, typename Setter2, typename Setter3, typename Setter4>
class PolicySelector
        : public Discriminator<Setter1, 1>, public Discriminator<Setter2, 2>, public Discriminator<Setter3, 3>,
          public Discriminator<Setter4, 4> {
};

class DefaultPolicyArgs : virtual public DefaultPolicies {
};

template<
        typename PolicySetter1 = DefaultPolicyArgs,
        typename PolicySetter2 = DefaultPolicyArgs,
        typename PolicySetter3 = DefaultPolicyArgs,
        typename PolicySetter4 = DefaultPolicyArgs>
class BreadSlicer {
    using Policies = PolicySelector<PolicySetter1, PolicySetter2, PolicySetter3, PolicySetter4>;

 public:
    void A() {
        Policies::P1::doSomething();
    }

    void B() {
        Policies::P2::doSomething();
    }

    void C() {
        Policies::P3::doSomething();
    }

    void D() {
        Policies::P4::doSomething();
    }

    void show() {
        A();
        B();
        C();
        D();
        cout << endl;
    }
};

int main() {
    BreadSlicer<> ex;
    ex.show();

    BreadSlicer<PolicySetter4<AA>, PolicySetter2<BB>>
            ex4;
    ex4.show();
}

我们修改了 第四个和第二个参数, 甚至第4个参数在第2个前面
在这里插入图片描述

#include <iostream>
#include <vector>
#include <memory>
#include <boost/type_index.hpp>

using namespace std;

class A {
 public:
    static void doSomething() {
        cout << "A::doSomething" << endl;
    }
};

class B {
 public:
    static void doSomething() {
        cout << "B::doSomething" << endl;
    }
};

class C {
 public:
    static void doSomething() {
        cout << "C::doSomething" << endl;
    }
};

class D {
 public:
    static void doSomething() {
        cout << "D::doSomething" << endl;
    }
};

class AA {
 public:
    static void doSomething() {
        cout << "*****************AA::doSomething" << endl;
    }
};

class BB {
 public:
    static void doSomething() {
        cout << "*****************BB::doSomething" << endl;
    }
};

class DefaultObj {
 public:
    using P1 = A;
    using P2 = B;
    using P3 = C;
    using P4 = D;
};

template<typename Base, size_t N>
class Fly : public Base {

};

class DefaultArgs : virtual public DefaultObj {

};

template<typename T>
class SetP1 : public DefaultArgs {
 public:
    using P1 = T;
};

template<typename T>
class SetP2 : public DefaultArgs {
 public:
    using P2 = T;
};

template<typename T, size_t Index>
struct Pack {
    using type = T;
    constexpr static auto value = Index;
};

template<typename ...Packs>
struct Policy : public Fly<typename Packs::type, Packs::value> ... {
};

template<typename ...Types, size_t ...Indexes>
auto makePolicy(index_sequence<Indexes...>) -> Policy<Pack<Types, Indexes>...> {}

template<typename ...Types>
using Selector_t = decltype(makePolicy<Types...>(make_index_sequence<sizeof...(Types)>{}));

template<typename T1 = DefaultArgs, typename T2 = DefaultArgs, typename T3 = DefaultArgs, typename T4 = DefaultArgs>
struct Slider {
    using Selector = Selector_t<T1, T2, T3, T4>;
    using P1 = typename Selector::P1;
    using P2 = typename Selector::P2;
    using P3 = typename Selector::P3;
    using P4 = typename Selector::P4;
    void A() {
        P1::doSomething();
    }

    void B() {
        P2::doSomething();
    }

    void C() {
        P3::doSomething();
    }

    void D() {
        P4::doSomething();
    }

    void show() {
        A();
        B();
        C();
        D();
    }
};

int main() {
    Slider<> d;
    d.show();
    cout << endl;

    Slider<SetP1<AA>, SetP2<BB>> xx;
    xx.show();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值