C/C++编程:模板中的命名参数

1059 篇文章 286 订阅

有些高级脚本语言,如Perl、PL/SQL等,他们的函数参数在调用时都支持命名参数,既在调用时可以不按照顺序传递参数,而是p可以按照参数的名字传递。模板中命名参数的实现如下

#include <iostream>
#include <cstring>


// PolicySelector 的任务是利用typedef将各个模板实参合并到一个单一的类型,即Discriminator;该类型能够根据指定的非缺省类型,改写缺省定义的typedef成员
// PolicySelector <A, B, C, D>生成A,B,C,D作为基类
// Discriminator<>使Policy Seletor可以多次继承自相同的基类

// 中间模板Discriminator的引入是为了一致的处理各个Setter类型(不能直接从多个相同类型的基类继承,但可以借助中间类间接继承)
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 DefaultPolicy1 {};
class DefaultPolicy2 {};
class DefaultPolicy3 {
public:
    static void doPrint(){
        printf("DefaultPolicy3::doPrint()\n");
    }
};
class DefaultPolicy4 {};

// 将缺省值集中到
//该类将会是所有Policy Class的基类。他提供了缺省的四个Policy的类型重定义。
//因此在缺省情况下,这四个Policy将会是BreadSlicer的四个Policy。
class DefaultPolicies {
public:
    typedef DefaultPolicy1 P1;
    typedef DefaultPolicy2 P2;
    typedef DefaultPolicy3 P3;
    typedef DefaultPolicy4 P4;
};

//这里之所以给出中间类DefaultPolicyArgs,同时又让该类以虚拟继承的方式继承
//DefaultPolicies,一是为了避免后面在多重继承同一基类时而导致的二义性,同时
//也是为了方便后面其他类的继承。
class DefaultPolicyArgs : virtual public DefaultPolicies {
};

template <typename Policy>
class Policy1_is : virtual public DefaultPolicies {
public:
    typedef Policy P1;  // overriding typedef
};

template <typename Policy>
class Policy2_is : virtual public DefaultPolicies {
public:
    typedef Policy P2;  // overriding typedef
};

template <typename Policy>
class Policy3_is : virtual public DefaultPolicies {
public:
    typedef Policy P3;  // overriding typedef
};

template <typename Policy>
class Policy4_is : virtual public DefaultPolicies {
public:
    typedef Policy P4;  // overriding typedef
};

template <typename PolicySetter1 = DefaultPolicyArgs,
        typename PolicySetter2 = DefaultPolicyArgs,
        typename PolicySetter3 = DefaultPolicyArgs,
        typename PolicySetter4 = DefaultPolicyArgs>
class BreadSlicer {
    typedef PolicySelector<PolicySetter1, PolicySetter2,
            PolicySetter3, PolicySetter4>
            Policies;
    // use Policies::P1, Policies::P2, //... to refer to the various policies.
public:
    void print () {
        Policies::P3::doPrint();
    }
    //...
};


// define a custom policy
class CustomPolicy {
public:
    static void doPrint() {
        std::cout << "CustomPolicy::doPrint()\n";
    }
};

int main()
{
    BreadSlicer<> bc1;
    bc1.print();

    BreadSlicer<Policy3_is<CustomPolicy> > bc2;
    bc2.print();
}

待研究博客:在现代C ++中引入命名参数

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值