最近看了看模板的元编程,感觉有点意思。
一些计算可以在编译过程就能够完成,榨干编译器的最后一点资源。
stl中用的全是这些玩意。
当然,这增加了编译时长。
我记得貌似有“图灵完备”这个说法——模板的元编程现在能够实现判断跳转、循环,理论上来说,一般能够用运行时解决的问题,在编译时都能够解决。
但这个好像没有什么意义。如果通篇都用这种代码来编写程序,那么这和直接嵌入汇编有什么区别?
我学这个纯属是为了让别人看不懂。
(我真的猜不透你耶……)
疯子就应该有疯子应该有的疯度。
写了几个小例子用来备忘。
学习参考链接: https://www.cnblogs.com/qicosmos/p/4480460.html
1.判断类型是否相同(C++自带也有 std::is_same<T1, T2>::value)
1 template <typename T1, typename T2> 2 struct is_same_type 3 { 4 enum { value = false }; 5 }; 6 7 template <typename T> 8 struct is_same_type<T, T> 9 { 10 enum { value = true }; 11 };
2.计算阶乘
1 //n! 2 template<int n> 3 struct factorial 4 { 5 private: 6 enum: unsigned long long { 7 tmp = n * factorial<n - 1>::value //It is useless. 8 }; 9 10 public: 11 enum { 12 value = tmp >= INT_MAX ? -1 : tmp //return n * factorial(n - 1); 13 }; 14 }; 15 16 template<> 17 struct factorial<0> //if(0 == n) 18 { 19 enum { value = 1 }; //return 1 20 };
3.获取一组数中最大的数
1 //get max number. 2 template<int n, int... ns> 3 struct max_num 4 { 5 enum {value = n}; //return n; 6 }; 7 8 template <int ln/*left number*/, int rn/*right number*/, int... ns/*numbers...*/> 9 struct max_num<ln, rn, ns...> 10 { 11 enum {value = 12 ln >= rn ? //if(ln >= rn) 13 max_num<ln, ns...>::value : //max_num(ln) 14 max_num<rn, ns...>::value // else max_num(rn) 15 }; 16 };
4.根据模板中不同的类型来获得不同的值(比如SocketTCP 和 SocketTCP 使用不同的协议类型和数据传输类型)
1 enum PROTO_TYPE 2 { 3 PROTO_NONE = 0, 4 PROTO1 = 1, 5 PROTO2 = 2 6 }; 7 8 class A 9 { 10 }; 11 12 class B 13 { 14 }; 15 16 template <class T> 17 struct getproto 18 { 19 enum { 20 value = //value = 21 std::is_same<T, A>::value ? PROTO1 : //if(typeT == typeA) return PROTO1; 22 std::is_same<T, B>::value ? PROTO2 : //else if(typeT == typeB) return PROTO2; 23 //TODO: others... 24 PROTO_NONE //else return PROTO_NONE; 25 }; 26 };
0.主函数用来测试
1 int main() 2 { 3 std::cout << "is_same_type: " <<is_same_type<int, int>::value << std::endl; 4 std::cout << "factorial:" << factorial<10>::value << std::endl; 5 std::cout << "max_num:"<< max_num<1, 2, 54, 2, 36, 4>::value << std::endl; 6 7 std::cout << "getproto: " << getproto<B>::value << std::endl; 8 9 system("pause>nul"); 10 return 0; 11 }