非类型模板参数(参考《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; // elementsstd::size_t numElems;        // current number of elementspublic:Stack();                   // constructorvoid push(T const& elem);  // push elementvoid pop();                // pop elementT const& top() const;      // return top elementbool empty() const {       // return whether the stack is emptyreturn numElems == 0;}std::size_t size() const { // return current number of elementsreturn 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 intsStack<int, 40>         int40Stack;     // stack of up to 40 intsStack<std::string, 40> stringStack;    // stack of up to 40 strings// manipulate stack of up to 20 intsint20Stack.push(7);std::cout << int20Stack.top() << '\n';int20Stack.pop();// manipulate stack of up to 40 stringsstringStack.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; // elementssize_type numElems;          // current number of elementspublic:Stack();                   // constructorvoid push(T const& elem);  // push elementvoid pop();                // pop element T const& top() const;      // return top elementbool empty() const {       // return whether the stack is emptyreturn numElems == 0;}size_type size() const {   // return current number of elementsreturn 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 intsStack<std::string, 40> stringStack;    // stack of up to 40 strings// manipulate stack of up to 20 intsint20Stack.push(7);std::cout << int20Stack.top() << '\n';auto size1 = int20Stack.size();// manipulate stack of up to 40 stringsstringStack.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';}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/407932.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

I AM NOTHING vs I AM SOMETHING

女友推荐链接&#xff1a;BBS上一个女生的创业感言 自创业的一路艰辛 http://bbs.trendsmag.com/showthread.php?t163960

DataGridView添加一行数据、全选、取消全选、清空数据、删除选中行

.net 2005下的Windows Form Application,一个DataGridView控件和4个Button&#xff0c;界面设置如下&#xff1a; 代码如下&#xff0c;有注解&#xff0c;相信大家都看得明白&#xff1a; using System;using System.Collections.Generic;using System.ComponentModel;using S…

类型萃取类型检查 Type-Traits LibraryType Checks --- C++20

类型萃取:类型检查 Type-Traits Library:Type Checks — C20 Type-Traits library 在C11的时候就已经发布,但依然随着C版本在不断更新 类型检查 Type Checks 每种类型就是十四种主要类型之一 主要类型 template <class T> struct is_void; template <class T>…

转:如何在 LoadRunner 脚本中做关联 (Correlation)

如何在 LoadRunner 脚本中做关联 (Correlation) 当录制脚本时&#xff0c;VuGen会拦截client端&#xff08;浏览器&#xff09;与server端&#xff08;网站服务器&#xff09;之间的对话&#xff0c;并且通通记录下来&#xff0c;产生脚本。在VuGen的Recording Log中&#xff0…

开博碎语

结束了5月26号的软考&#xff0c;就萌生了建一个技术博客的想法-----技术或许太空泛&#xff0c;其实就是把工作中&#xff0c;学习上技术方面的一些资料&#xff0c;一些体会汇聚一起&#xff0c;呈现出来&#xff0c;博客当然是个不错的选择。baidu一下&#xff0c;技术博客为…

DateTime时间的比较问题

关于DateTime时间的比较问题&#xff0c;我现在不清楚使用> < 和DateTime.Compare(t1, t2)、t1.CompareTo(t2)的区别。 下面是一个简单的测试程序&#xff0c;至少到现在为止&#xff0c;我还没有发现这两种比较的区别之处&#xff0c;大家有任何自己的想法&#xff0c;…

模板元编程 Template Metaprogramming--- C++ 20

模板元编程(一) Template Metaprogramming— C 20 在编译期进行类型操作 举个例子: std::move在概念上应该这样实现(实际并不是这么做的): static_cast<std::remove_reference<decltype(arg)>::type&&>(arg);意义上,std::move首先获取它的参数arg,推断…

6月,启蒙篇

6月&#xff0c;哈哈 在过去的4月与5月里我一直放荡着自己&#xff0c;我发现一个人没有目标与理想后是这样的无耐 &#xff0c;也是这样的无所做为。在那两个月里我放弃了所有的程序&#xff0c;我只是在计算机前玩游戏 。我原本以为这样会过得开心点&#xff0c;会让自己放松…

JS 计算日期天数差

function dayDiffer(startDate,endDate){console.info((endDate.getTime - startDate.getTime())/(24*60*60*1000));return Math.floor((endDate.getTime() - startDate.getTime())/(24*60*60*1000)); }转载于:https://www.cnblogs.com/jsczljh/p/3647395.html

自定义控件-实现TextBox的禁止粘贴

开发环境&#xff1a;Visual Studio .net 2005 Windows XP sp2 professional 新建->项目&#xff0d;>Windows控件库: 新建一个类&#xff0c;继承自TextBox类&#xff0c;具体源代码如下&#xff1a; using System;using System.Collections.Generic;using System.Comp…

模板元编程(二) Template Metaprogramming ---C++ 20

模板元编程(二) Template Metaprogramming —C 20 现在我们介绍参数与模板参数混合使用 先看一下例子: #include <iostream>int power(int m, int n) {int r 1;for (int k 1; k < n; k) r * m;return r; }template <int m, int n> struct Power {static in…

探索 ASP.NET Futures (Part 2 - Search Enabled)

在本系列的上一篇文章中&#xff0c;我们探索了ASP.NET Futures (May CTP)的SearchSiteMap功能&#xff0c;说明了如何将ASP.NET的SiteMap影射为符合Sitemaps协议的XML以便搜索引擎更好的抓取我们的站点。然而让搜索引擎更好的抓取我们的站点了&#xff0c;这部分的优化却仅仅对…

让窗体获得焦点,一定会有您用到的时候

开发环境&#xff1a;Visual Studio .NET 2005 下的Windows Form Application 应用场景: 当我们有个窗体中的数据发生了变化而此窗体又没有获得焦点(不是用户操作的当前窗口)的时候&#xff0c;我们希望它获得焦点&#xff0c;这样用户就可以立刻发现它上面的数据发生了变化。…

容器和算法的改进 --- C++20

容器和算法的改进 — C20 C 20对容器和算法有很多的改进 std::vector 和std::string支持constexpr所有容器支持consistent container erasure , contains新的算法移动元素 std::shift_left可以检查 std::string 的前缀和后缀 支持 constexpr 的容器和算法 C 20的std::vecto…

CodeSmith基础(二)

本文将介绍CodeSmith与数据库进行交互生成相应的存储过程&#xff0c;本例使用的数据库为SQL Server 2000。 在与数据库进行交互时&#xff0c;我们使用到了一个CodeSmith自带的组件SchemaExplorer&#xff0c;利用这个组件我们可以访问数据库的数据表、存储过程、视图等…

[Android]使用ViewPager实现图片滑动展示

在淘宝等电商的APP首页经常能看到大幅的广告位&#xff0c;通常有多幅经常更新的图片用于展示促销信息&#xff0c;如下图所示&#xff1a; 通常会自动滚动&#xff0c;也可以根据手势滑动。我没有研究过人家的APP是通过什么实现的&#xff0c;可能有第三方已经封装好的控件可以…