编译期运算
最近在研究C++模版,发现一个以前没有遇到过的技术,就是编译期计算。
所谓编译期运算就是指在编译阶段由编译器所进行的运算,不占用运行期时间,有时也称元模版编程。
所有可以在编译期决定的数值都可以用这种方法解决以节省运行时的浪费,只是这种方法毫无灵活性可言,平时用得很少,仅了解一下即可。
以下运算不消耗运行时,全部数值计算在编译时就已经完成。
#include <iostream>
template <int _P, int _Q = _P>
class IsPrime
{
public:
enum{result = (_P % (_Q - 1) ) && IsPrime<_P, _Q - 1>::result };
};
template <int _P>
class IsPrime<_P, 2>
{
public:
enum{ result = 1};
};
template<bool C, typename Ta, typename Tb>
class IfThenElse
{
public:
typedef Tb ResultT;
};
template<typename Ta, typename Tb>
class IfThenElse<true, Ta, Tb>
{
public:
typedef Ta ResultT;
};
template <int _P, int _Q = 0>
class CountPrime
{
public:
typedef typename IfThenElse<IsPrime<_P>::result,
CountPrime<_P - 1, _Q + 1>,
CountPrime<_P - 1, _Q> >::ResultT
SubT;
enum { result = SubT::result };
};
template <int _Q>
class CountPrime<2, _Q>
{
public:
enum{result = _Q + 1 };
};
int main()
{
std::cout << IsPrime<33>::result << std::endl; //判断素数
std::cout << IsPrime<11>::result << std::endl;
std::cout << IsPrime<7>::result << std::endl;
std::cout << IsPrime<179>::result << std::endl;
std::cout << CountPrime<100>::result << std::endl; //统计x以内素数
system("pause");
}
template <int _P, int _Q = _P>
class IsPrime
{
public:
enum{result = (_P % (_Q - 1) ) && IsPrime<_P, _Q - 1>::result };
};
template <int _P>
class IsPrime<_P, 2>
{
public:
enum{ result = 1};
};
template<bool C, typename Ta, typename Tb>
class IfThenElse
{
public:
typedef Tb ResultT;
};
template<typename Ta, typename Tb>
class IfThenElse<true, Ta, Tb>
{
public:
typedef Ta ResultT;
};
template <int _P, int _Q = 0>
class CountPrime
{
public:
typedef typename IfThenElse<IsPrime<_P>::result,
CountPrime<_P - 1, _Q + 1>,
CountPrime<_P - 1, _Q> >::ResultT
SubT;
enum { result = SubT::result };
};
template <int _Q>
class CountPrime<2, _Q>
{
public:
enum{result = _Q + 1 };
};
int main()
{
std::cout << IsPrime<33>::result << std::endl; //判断素数
std::cout << IsPrime<11>::result << std::endl;
std::cout << IsPrime<7>::result << std::endl;
std::cout << IsPrime<179>::result << std::endl;
std::cout << CountPrime<100>::result << std::endl; //统计x以内素数
system("pause");
}
另外还可以用这个技术写出其他的运算函数,不过代码既不灵活,对模版不熟悉的人来说又晦涩难以维护,所以不太推荐。
真正把模版用得出神入化而且非常实用的是Loki库,大家可以参考《Morded C++ Design》这本书,第一次看到这本书的时候,让我大大地开了眼界,以至对C++产生了陌生感。