“”
猛戳订阅🍁🍁 👉 [C++详解专栏] 👈 🍁🍁
概念:
编写与类型无关的通用代码,达成代码复用,模板是泛型编程的基础。
模板就是把工作交给编译器去做。让编译器去生成多个函数,省的我们再去写函数模板。比如Add加法函数。
平时经常用的是函数模板和类模板
函数模板格式:
template<typename T1,typename T2,typename T3.....>
这里需要有个感性的认知:
1.一个模板参数只能定义一个函数。模板参数可以有缺省参数。
2.模板参数是类型。函数参数是对象。
模板参数传递的是类型,函数参数传递的是对象值。
3.普通函数是有地址的,而模板函数没有地址。
但是模板会推算,会通过实参传递给形参,推算他的实际类型。
template<typename T>
void Swap(T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
实例化:用不同类型的参数使用函数模板时,称为函数模板的实例化
但是有时候也有例外。需要显式实例化。
代码如下
template<class T>
T* func(int n)
{
return new T[n];
}
int main()
{
int* p = func<int>(10);
return 0;
}
typename是用来定义模板参数的关键字。也可以用class.但是不能用struct。
1.类模板和函数模板不同。函数模板一般可以显式传参推出实际类型。
2.而类模板不能传参推断类型,所以类模板需要在类名的 后面加尖括号<>里面加类型,这叫做类模板的显式实例化
例如:
vector<int> v1;//int类型
vector<double> v2;//元素是double类型
注意:
cao不是具体的一个类,而是编译器根据被实例化的类型生成具体类的模具。
template<class T1, class T2>
class 类模板名
{
//类内成员定义
};
//类模板
template<class T>
class cao
{
};
//类模板的实例化
cao<int> c;
//cao类名,cao<int>才是类型
概念:非类型形参。就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常量来使用
1.非类型的模板参数无法修改
2.浮点数,类对象以及字符串无法做非类型模板参数
(非类型模板参数一般是整形)
3.非类型的模板参数必须在编译期间就能确认结果。
N就是非类型形参。
template<class T, size_t N = 10>
使用模板可以实现与类型无关的代码。但有时候还需要做一些特殊处理。
特化步骤
1.必须要先有一个基础的函数模板
2.关键字template后面接一对空的尖括号<>
3.函数名后跟一对尖括号,尖括号中指定需要特化的类型。
4.函数形参表:必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇怪错误
struct Date
{
int _year = 1;
int _month = 1;
int _day = 1;
};
//基础的函数模板
template<class T>
bool IsEqual(T left, T right)
{
return left == right;
}
//关键字template后面接一对空的尖括号<>
template<>
//函数名后跟一对尖括号,尖括号中指定需要特化的类型
//函数形参表:必须要和模板函数的基础参数类型完全相同
bool IsEqual<Date*>(Date* left, Date* right)
{
return left->_year == right->_year
&& left->_month == right->_month
&& left->_day == right->_day;
}
int main()
{
cout << IsEqual(1, 2) << endl;
Date* p1 = new Date;
Date* p2 = new Date;
cout << IsEqual(p1, p2) << endl;
return 0;
}
全特化就指的是模板参数列表中所有的参数都确定化。
//全特化
template<class T1, class T2>
class Data
{
public:
Data()
{
cout << "Data<T1, T2>" << endl;
}
private:
T1 _d1;
T2 _d2;
};
//跟一对尖括号<>
template<>
class Data<int, char>
{
public:
Data()
{
cout << "Data<int,char>" << endl;
}
private:
int _d1;
char _d2;
};
int main()
{
Data<int, int> d1;
//模板的全特化
Data<int, char> d2;
}
偏特化是针对模板参数进一步进行条件限制设计的特化版本。
//类的基础模板
template<class T1, class T2>
class Data
{
public:
Data()
{
cout << "Data<T1, T2>" << endl;
}
private:
T1 _d1;
T2 _d2;
};
//1.部分特化
//将模板参数列表中的一部分参数特化。
template <class T1>
class Data<T1, int>
{
public:
Data()
{
cout << "Data<T1, int>" << endl;
}
private:
T1 _d1;
int _d2;
};
//两个参数偏特化为引用类型
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:
Data() { cout << "Data<T1*, T2*>" << endl; }
private:
T1 _d1;
T2 _d2;
};
//两个参数偏特化为引用类型
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:
Data(const T1& d1, const T2& d2)
:_d1(d1)
, _d2(d2)
{
cout << "Data<T1&, T2&>" << endl;
}
private:
const T1& _d1;
const T2& _d2;
};
int main()
{
Data<double, int> d1;
Data<int, double> d2;
Data<int*, int*> d3;
Data<int&, int&> d4(1,2);
}
一个程序由若干个源文件组成。而每个源文件单独编译成目标文件,然后目标文件链接起来形成可执行文件的过程称为分离编译。
模板一般不支持分离编译。但普通函数是可以的。
C/C++程序要运行,基本步骤.
预处理 -> 编译->汇编->链接
函数模板的声明和定义也有一些讲就。
声明:
template<typename T>
void Swap(T& left, T& right);
定义:
template<typename T>
void Swap(T& left, T& right)
{
T temp = left;
left = right;
right = temp;
}
注意:类模板的定义还需要加上类域。
a.cpp

a.h

main.cpp

a.h头文件不参与编译。
a.cpp中不会生成模板函数的实例化,
main.cpp中调用函数链接时找地址。main.cpp包含的头文件只有a.h的。但是a.cpp中没有实例化所以没有地址。
解决方法:
1.将声明和定义放到一个文件.hpp的文件中。
2.模板定义的位置显式实例化。(不推荐使用).
模板的优点:
1.模板复用了代码,节省了资源。STL标准模板库因此而产生。
2.增强了代码的灵活性。
缺点:
1.模板会导致代码膨胀,也会导致编译时间变长。
2.出现模板编译错误时,错误信息非常凌乱,不易定位错误。
符号表找不到。
和实例化有关系。
a.cpp 从预处理到 a.i经过了头文件的展开。
a.i经编译到a.s再经过汇编到a.o什么都没干,因为模板的类型没有确定,所以没法实例化。a.s和a.o都是空的,空壳子。
解决办法:
1.显示实例化,太矬了,几乎不用这个办法。
2.不分离到两个文件中,放到同一个文件中。这样为什么就可以了呢?
为什么就不存在链接错误了?**原因是因为在main.cpp中头文件展开后,有了函数模板的声明和定义。**在链接的时候就不用找他的地址了。
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我正在使用Mandrill的RubyAPIGem并使用以下简单的测试模板:testastic按照Heroku指南中的示例,我有以下Ruby代码:require'mandrill'm=Mandrill::API.newrendered=m.templates.render'test-template',[{:header=>'someheadertext',:main_section=>'Themaincontentblock',:footer=>'asdf'}]mail(:to=>"JaysonLane",:subject=>"TestEmail")do|format|format.h
所以这可能有点令人困惑,但请耐心等待。简而言之,我想遍历具有特定键值的所有属性,然后如果值不为空,则将它们插入到模板中。这是我的代码:属性:#===DefaultfileConfigurations#default['elasticsearch']['default']['ES_USER']=''default['elasticsearch']['default']['ES_GROUP']=''default['elasticsearch']['default']['ES_HEAP_SIZE']=''default['elasticsearch']['default']['MAX_OP
一般来说,我是Middleman和ruby的新手。我已经安装了Ruby我已经安装了Middleman和gem以使其运行。我需要使用slim而不是默认的模板系统。所以我安装了Slimgem。Slim的网站只说我需要'slim'才能让它工作。中间人网站说我只需要在config.rb文件中添加模板引擎,但是没有给出例子...对于没有ruby背景的人来说,这没有帮助。我在git上找了几个config.rb,它们都有:require'slim'和#Setslim-langoutputstyleSlim::Engine.set_default_options:pretty=>true#Se
我有一个偏爱:如何将像o.office这样的值插入到属性中?value="#{o.office}"无效。 最佳答案 'type='text'/>或者你可以使用表单助手 关于ruby-on-rails-如何将变量值插入ERB模板中的HTML标签?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/6172174/
有没有办法在liquidtemplate中输出(用于调试/信息目的)可用对象和对象属性??也就是说,假设我正在使用jekyll站点生成工具,并且我在我的index.html模板中(据我所知,这是一个液体模板)。它可能看起来像这样{%forpostinsite.posts%}{{post.date|date_to_string}}»{{post.title}}{%endfor%}是否有任何我可以使用的模板标签会告诉我/输出名为post的变量在此模板(以及其他模板)中可用。此外,是否有任何模板标签可以告诉我post对象具有键date、title、url、摘录、永久链接等
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visitthehelpcenter.关闭11年前。哪些模板引擎/模板语言是图灵完备的?到目前为止,我听说过这些:FreeMarker(用java实现)MovableTypes模板语言(perl)xslt:-(Cheetah(Python语言)聪明(PHP)还有其他的(特别是用perl实现的)吗?Ps:不要浪费时间向我解释MVC,以及为什么图灵完整模板不好,以及为什么这不是一个有用的比较点:)
我知道我可以用这段代码迭代liquid模板中的数组:{%foriteminmyarray%}{{item.label}}但是我怎样才能得到我的项目在数组中的索引呢? 最佳答案 根据"LiquidforDesigners"liquid的github部分...forloop.length#=>lengthoftheentireforloopforloop.index#=>indexofthecurrentiterationforloop.index0#=>indexofthecurrentiteration(zerobased)forl
究竟如何使用Liquid中的map过滤器?我在Jekyll中使用它。---my_array:[apple,banana,orage]my_map:hello:worldfoo:barmy_string:"howdoesthiswork?"---{{page.my_map|map...}}这就是我迷路的地方。我似乎无法在文档或任何其他在线网站上找到任何关于它的用法示例。顺便说一下,我还不懂Ruby,所以sourcecode我也不清楚。来自filtertests看起来下面应该产生一些东西,但在GitHub上,我什么也没得到:{{site.posts|map:'title'|array_to
我有一些nginx站点的资源和提供程序,它可以为站点写出配置文件。action:startdotemplate"/etc/nginx/sites-enabled/my_site"dosource"nginx_site.conf.erb"notifies:reload,"service[nginx]"endend当我从另一本Recipe中使用它时,找不到模板nginx_site.conf.erb,因为Chef正在寻找调用此资源的模板。有没有办法告诉Chef在nginx资源和提供者Recipe中寻找模板? 最佳答案 您可以为templa