场景如下
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();
}