泛化编程及模板元编程入门

1. 全特化和偏特化

https://harttle.land/2015/10/03/cpp-template.html

2. 模板元编程

例子1 在编译阶段实现阶乘

使用enum编译实现

#include <iostream>
using namespace std;

template<unsigned N>
struct Factorial {
    enum {VALUE=N*Factorial<N-1>::VALUE};
};

template<>
struct Factorial<0> {
    enum {VALUE=1};
};

int main(){
    Factorial <5> F;
    cout << F.VALUE;

    return 0;
}

使用static const T编译实现

#include <iostream>
using namespace std;

template<unsigned N>
struct Factorial {
    enum haha{VALUE=N*Factorial<N-1>::VALUE};
};

template<>
struct Factorial<0> {
    enum haha{VALUE=1};
};

int main(){
    Factorial <5> F;
    cout << F.VALUE << endl;
    cout << typeid(F.VALUE).name()<<endl;
    cout << typeid(F).name() << endl;

    return 0;
}

运行结果

120
enum Factorial<5>::haha
struct Factorial<5>

或者这样写:

#include <iostream>
using namespace std;

template<unsigned N>
struct Factorial {
    static const unsigned VALUE=N*Factorial<N-1>::VALUE;
};

template<>
struct Factorial<0> {
    static const unsigned VALUE = 1;
};

int main(){
    Factorial <5> F;

    cout << F.VALUE << endl;
    cout << typeid(F.VALUE).name()<<endl;

    return 0;
}

因为编译的时候只能知道常量,所以VALUE要加上const,由于递归的需要,故加上static

例子2 再进一步泛化

实现乘方的功能

可以使用函数模板:

template<unsigned N>
inline double power(double v){
    return v*power<N-1>(v);
}

template<>
inline double power<1>(double v){
    return v;
}

由于需要在编译阶段进行运算,故需使用inline关键字

进一步泛化

上述代码只针对double型变量有效,为了方便可进一步进行泛化:

#include <iostream>
using namespace std;

template<unsigned N>
struct Power {
    template<class T>
    static T value(T x) {/*写成static const T value(T x)也可以 */
        return x * Power<N - 1>::value(x);
    }
};

template<>
struct Power<1> {
    template<class T>
    static T value(T x) {/*写成static const T value(T x)也可以 */
        return x;
    }
};

int main(){
    int F=Power <4> ::value(3);

    cout << F << endl;
    cout << typeid(F).name()<<endl;

    return 0;
}

由于函数模板不可偏特化,所以不能直接指定N=1的计算结果,所以可以把整体写一个类,再实现偏特化。具体做法是把赋值语句写在类的成员函数中,上面的代码const是否存在,运行结果都相同。

调用方式:

int x=5;
Power <4> ::value(x);

简化函数的调用

或者可对上述代码的调用进行简化,设计一个辅助的函数模板:

#include <iostream>
using namespace std;

template<unsigned N>
struct Power {
    template<class T>
    static const T value(T x) {
        return x * Power<N - 1>::value(x);
    }
};

template<>
struct Power<1> {
    template<class T>
    static const T value(T x) {
        return x;
    }
};

template<unsigned N, class T>
inline T Power1(T v) {
    return Power<N>::value(v);
}

int main(){
    int F=Power <4> ::value(3);
    cout << F << endl;
    cout << typeid(F).name()<<endl;

    double f = 2;
    //cout << Power1<2, double>(f);也可以
    cout << Power1<2>(f);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值