变量模板和非类型模板参数
1 // 变量模板 2 template<typename T> 3 constexpr T pi = T(3.14159265358979323846);
1 // 定义变量模板 2 template<typename T> 3 constexpr T max_value = std::numeric_limits<T>::max(); 4 5 template<typename T> 6 constexpr T pi_v = T(3.14159265358979323846); 7 8 template<typename T> 9 constexpr T e_v = T(2.71828182845904523536); 10 11 int main() 12 { 13 std::cout << "Max int: " << max_value<int> << std::endl; 14 std::cout << "Max double: " << max_value<double> << std::endl; 15 16 std::cout << "Pi as float: " << pi_v<float> << std::endl; 17 std::cout << "Pi as double: " << pi_v<double> << std::endl; 18 19 std::cout << "e as float: " << e_v<float> << std::endl; 20 std::cout << "e as double: " << e_v<double> << std::endl; 21 return 0; 22 }
输出如下:
Max int: 2147483647 Max double: 1.79769e+308 Pi as float: 3.14159 Pi as double: 3.14159 e as float: 2.71828 e as double: 2.71828
1 // 主模板 2 template<typename T> 3 constexpr T default_value = T{}; 4 5 // 全特化 6 template<> 7 constexpr int default_value<int> = 42; 8 9 template<> 10 constexpr double default_value<double> = 3.14; 11 12 13 // std::string 不能用作 constexpr,下面代码有错 14 // template<> 15 // constexpr std::string default_value<std::string> = "Hello"; 16 17 template<> 18 constexpr const char* default_value<const char*> = "Hello"; 19 20 21 // 偏特化(通过重载实现类似效果) 22 template<typename T> 23 constexpr T* default_value<T*> = nullptr; 24 25 int main() 26 { 27 std::cout << "Default int: " << default_value<int> << std::endl; 28 std::cout << "Default double: " << default_value<double> << std::endl; 29 std::cout << "Default const char*: " << default_value<const char*> << std::endl; 30 std::cout << "Default int*: " << default_value<int*> << std::endl; 31 return 0; 32 }
Default int: 42 Default double: 3.14 Default const char*: Hello Default int*: 0
template<int N> constexpr int fibonacci = fibonacci<N - 1> +fibonacci<N - 2>; template<> constexpr int fibonacci<0> = 0; template<> constexpr int fibonacci<1> = 1;
基本用法
1 // 整型类型 2 template<int N> 3 class Array 4 { 5 public: 6 int data[N]; 7 int size() const { return N; } 8 }; 9 10 // 指针类型 11 template<const char* Str> 12 class StringWrapper 13 { 14 public: 15 const char* get() const { return Str; } 16 }; 17 18 // 引用类型 19 template<int& Ref> 20 class ReferenceWrapper 21 { 22 public: 23 int get() const { return Ref; } 24 void set(int value) { Ref = value; } 25 }; 26 27 // 枚举类型 28 enum class Color { Red, Green, Blue }; 29 template<Color C> 30 class ColorTemplate 31 { 32 public: 33 static constexpr Color value = C; 34 };
编译时计算
1 template<int N> 2 constexpr int factorial = N * factorial<N-1>; 3 4 template<> 5 constexpr int factorial<0> = 1; 6 7 template<int Base, int Exp> 8 constexpr int power = Base * power<Base, Exp - 1>; 9 10 template<int Base> 11 constexpr int power<Base, 0> = 1; 12 13 int main() 14 { 15 std::cout << "Factorial(5): " << factorial<5> << std::endl; 16 std::cout << "2^5 = " << power<2, 5> << std::endl; 17 return 0; 18 }
Factorial(5): 120 2^5 = 32
1 constexpr int arr[3] = {1, 2, 3}; 2 template<const int* P> struct ArrayPtr {}; 3 4 int main() 5 { 6 constexpr int arr2[3] = {1, 2, 3}; 7 ArrayPtr<arr> a; 8 ArrayPtr<arr2> b; // error: 'arr2' is not a valid template argument of type 'const int*' because 'arr2' has no linkage 9 }
1 // 使用 static 2 int main() 3 { 4 static constexpr int arr2[3] = {1, 2, 3}; // 内部链接 5 ArrayPtr<arr2> b; // 现在合法 6 } 7 8 // 使用命名空间作用域 9 namespace 10 { 11 constexpr int arr2[3] = {1, 2, 3}; // 内部链接 12 } 13 14 int main() 15 { 16 ArrayPtr<arr2> b; // 合法 17 }

浙公网安备 33010602011771号