STL基础(四)非类型模板参数

1、非类型模板参数

前面两篇文章中举的例子中模板参数都是类型,但是在C++模板编程中,模板参数不仅仅可以是类型,也可以是非类型。这里举个简单的例子:

template <int N>
void print() {
    std::cout << N << std::endl;
}

int main() {
    MyTemplate::print<3>();		// 3
}

例中print的模板参数是一个int,并不是我们之前所使用的<typename T>

非类型模板参数可以是以下几种类型:

  • 整型或者枚举
  • 指向对象或者函数的指针
  • 引用类型
  • 指向成员的指针
  • std::nullptr_t
template<int SIZE> 
class A{ /*...*/ };         // 整型非类型模板参数

template<char *p> 
class X { /*...*/ };        // 指针非类型模板参数,全局/静态变量指针

template<int ( *func)(int)> 
struct Y { /*...*/ };       // 函数指针非类型模板参数

template<int& R> 
struct Z { /*...*/ };       // 引用非类型模板参数,需引用全局/静态变量

struct C { int m; };
template<int C::* M> 
struct Q { /*...*/ };       // 指向成员的指针非类型模板参数

非常注意的是:非类型模板参数的值必须在编译期确定

编译期可以确定的值或变量有如下几个:

  • 字面量:例如整数、字符、布尔值等,浮点型并不属于编译器可以确定的;
template<int N>
struct Constant {
    static const int value = N;
};
constexpr int a = Constant<5>::value;
  • 全部变量或静态变量的地址或引用
char g_s[] = "abc";
template<char *p>
struct Test() {
    void print { std::cout << p << std::endl; }
};
Test<g_s> obj;
  • 全局或静态函数的地址(函数指针)
void print() {
    std::cout << "Hello Function" << std::endl;
}
template<void (*func)()>
struct TestFunction {
    void exec() { func(); }
};
TestFunction<print> testFunction;
testFunction.exec();
  • 枚举enum
enum class Color { Red, Blue, Green };
template<Color color>
struct Test {

};
Test<Color::Red> obj; // 使用Color::Red模板实例化Test
  • 指向成员的指针
struct Example { int value; };

template<int Example::*ptr>
struct Test2 {
	void print(Example& e) {
		std::cout << e.*ptr << std::endl;
	}
};

Example e;
e.value = 10;
Test2<&Example::value> obj2;
obj2.print(e);

成员指针可能会比较让人疑惑,Example::*ptr表示Example中的某个成员,int限定了这个成员的类型,更多的成员指针内容可参考:

这里有一点要注意,非类型模板参数如果是指向成员的指针,指向的类型可以是任意类型

struct Example { 
    int value; 
    People p;
};
template<People Example::*ptr>
struct Test2 {
	void print(Example& e) {
		std::cout << e.*ptr << std::endl;
	}
};

非类型模板参数就暂时先了解到这,我们需要记住的是,C++模板参数不仅仅可以是类型,还可以是编译期可以确定的值或者是变量。

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-21 21:28:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-21 21:28:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-21 21:28:03       87 阅读
  4. Python语言-面向对象

    2024-04-21 21:28:03       96 阅读

热门阅读

  1. 【创建git仓库并关联github账户】

    2024-04-21 21:28:03       41 阅读
  2. Python模块之logging

    2024-04-21 21:28:03       97 阅读
  3. React中 useReducer的使用

    2024-04-21 21:28:03       38 阅读
  4. ubuntu在docker容器中安装strongswan

    2024-04-21 21:28:03       35 阅读
  5. 一些linux命令

    2024-04-21 21:28:03       33 阅读
  6. 物联网与服务器有什么样的联系?

    2024-04-21 21:28:03       38 阅读
  7. C++笔记打卡第17天(STL、容器)

    2024-04-21 21:28:03       37 阅读