IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 非类型模板参数(参考《C++ Templates 英文版第二版》) -> 正文阅读

[C++知识库]非类型模板参数(参考《C++ Templates 英文版第二版》)

非类型模板参数(参考《C++ Templates 英文版第二版》)

Chapter 3

3.1 非类型类模板参数

与前几章的简单例子不同,你也可以通过std::array实例化一个固定大小的栈,这样做的优点在于内存管理,

#include <array>
#include <cassert>

template<typename T, std::size_t Maxsize>
class Stack {
  private:
    std::array<T,Maxsize> elems; // elements
    std::size_t numElems;        // current number of elements
  public:
    Stack();                   // constructor
    void push(T const& elem);  // push element
    void pop();                // pop element
    T const& top() const;      // return top element
    bool empty() const {       // return whether the stack is empty
        return numElems == 0;
    }
    std::size_t size() const { // return current number of elements
        return numElems;
    }
};

template<typename T, std::size_t Maxsize>
Stack<T,Maxsize>::Stack ()
 : numElems(0)                 // start with no elements
{
    // nothing else to do
}

template<typename T, std::size_t Maxsize>
void Stack<T,Maxsize>::push (T const& elem)
{
    assert(numElems < Maxsize);
    elems[numElems] = elem;    // append element
    ++numElems;                // increment number of elements
}

template<typename T, std::size_t Maxsize>
void Stack<T,Maxsize>::pop ()
{
    assert(!elems.empty());
    --numElems;                // decrement number of elements
}

template<typename T, std::size_t Maxsize>
T const& Stack<T,Maxsize>::top () const
{
    assert(!elems.empty());
    return elems[numElems-1];  // return last element
}

运行一下:

#include "stacknontype.hpp"
#include <iostream>
#include <string>

int main()
{
	Stack<int, 20>         int20Stack;     // stack of up to 20 ints
	Stack<int, 40>         int40Stack;     // stack of up to 40 ints
	Stack<std::string, 40> stringStack;    // stack of up to 40 strings

	// manipulate stack of up to 20 ints
	int20Stack.push(7);
	std::cout << int20Stack.top() << '\n';
	int20Stack.pop();

	// manipulate stack of up to 40 strings
	stringStack.push("hello");
	std::cout << stringStack.top() << '\n';
	stringStack.pop();
}

你也可以设置默认参数

template<typename T, std::size_t Maxsize = 100>,但最好不要这样做,因为栈大小最好还是有程序员自己控制

3.2 非类型函数模板参数

你也可以为函数定义非类型模板参数

template<int val,typename  T>
int addval(T a)
{
	return a + val;
}
int main()
{
	std::cout << addval<10>(10) << std::endl;
}

这种函数是很有用的,可以将它作为参数.

例如,如果你可以使用STL,你可以传入一个函数模板的实例,使集合中的每个数加一个值

	std::vector<int> source{ 1,4,5 };
	std::vector<int> dest{0,0,0};
	std::transform(source.begin(), source.end(), dest.begin(), addval<10,int>);
	for (auto value : dest)
	{
		std::cout << value << std::endl;
	}

如果你制定非类型函数模板参数是int那么就无法使用其他类型,是有什么方法可以做到自动推导其他类型呢?

其实,你可以指定一个根据之前的模板参数推断出来的模板参数

template<auto val,typename  T = decltype(val)>
T addval(T a)
{
	return a + val;
}

3.3 非类型模板参数的限制

非类型模板参数有一些限制,例如,它们只能是整数,(对象,函数,成员)指针,(对象,函数,成员)引用,std::nullptr

浮点数指针和类对象不可以作为非类型模板参数

3.4 模板参数类型auto

C++17 ,你可以定义一个非类型模板模板参数去普遍的接收任何类型,使用这个特性,你可以定义一个更加一般的固定大小栈

#include <array>
#include <cassert>

template<typename T, auto Maxsize>
class Stack {
  public:
    using size_type = decltype(Maxsize);
  private:
    std::array<T,Maxsize> elems; // elements
    size_type numElems;          // current number of elements
  public:
    Stack();                   // constructor
    void push(T const& elem);  // push element
    void pop();                // pop element 
    T const& top() const;      // return top element
    bool empty() const {       // return whether the stack is empty
        return numElems == 0;
    }
    size_type size() const {   // return current number of elements
        return numElems;
    }
};

// constructor
template<typename T, auto Maxsize>
Stack<T,Maxsize>::Stack ()
 : numElems(0)                 // start with no elements
{
    // nothing else to do
}

template<typename T, auto Maxsize>
void Stack<T,Maxsize>::push (T const& elem)
{
    assert(numElems < Maxsize);
    elems[numElems] = elem;    // append element
    ++numElems;                // increment number of elements
}

template<typename T, auto Maxsize>
void Stack<T,Maxsize>::pop ()
{
    assert(!elems.empty());
    --numElems;                // decrement number of elements
}

template<typename T, auto Maxsize>
T const& Stack<T,Maxsize>::top () const
{
    assert(!elems.empty());
    return elems[numElems-1];  // return last element
}

运行:

Stack<int, 20u>        int20Stack;     // stack of up to 20 ints
    Stack<std::string, 40> stringStack;    // stack of up to 40 strings

    // manipulate stack of up to 20 ints
    int20Stack.push(7);
    std::cout << int20Stack.top() << '\n';
    auto size1 = int20Stack.size();

    // manipulate stack of up to 40 strings
    stringStack.push("hello");
    std::cout << stringStack.top() << '\n';
    auto size2 = stringStack.size();

    if (!std::is_same_v<decltype(size1), decltype(size2)>) {
        std::cout << "size types differ" << '\n';
    }
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-28 00:06:47  更:2021-09-28 00:07:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/25 22:00:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码