#include "D:\C++WORK\main.h"
template<typename T1,typename T2>
T1 & print(T1 & s,T2 val)
{
s<<val;
return s;
}
int main()
{
double dval=0.88;
float fval=-12.3;
string oristr="this is a test ",desstr;
ostringstream oss(desstr);
ofstream outFile("result.dat");
//写至cout
print(cout,-3)<<endl;
print(cout,dval)<<endl;
print(cout,fval)<<endl;
print(cout,oristr)<<endl;
//写至文件
print(outFile,-3)<<endl;
print(outFile,dval)<<endl;
print(outFile,fval)<<endl;
print(outFile,oristr)<<endl;
outFile.close();//对文件写完之后,需要关闭文件
//写至stringstream
print(oss,-3)<<endl;
print(oss,dval)<<endl;
print(oss,fval)<<endl;
print(oss,oristr)<<endl;
//将stringstream中的字符串输出到cout以验证
cout<<oss.str()<<endl;
/*【】【】【】【】【】【】【】【】【】【】【】【】 关于stringstream::str()函数的用法【】【】【】【】【】【】【】【】【】【】【】【】
Get/set content 获取和设置内容
The first form (1) returns a string object with a copy of the current contents of the stream.
The second form (2) sets s as the contents of the stream, discarding any previous contents.
The object preserves its open mode: if this includes ios_base::ate, the writing position is moved to the end of the new sequence.
Internally, the function calls the str member of its internal string buffer object.
int main ()
{
std::stringstream ss;
ss.str ("Example string");//设置ss的数值
std::string s = ss.str();//获取ss的数值
std::cout << s << '\n';
return 0;
}
*/
return 0;
}
/*-------------------------------------------------------------------------------
编写一个函数模板,接受表示未知类型迭代器的一对值,找出在序列中出现得最频繁的值。
---------------------------------------------------------------------------------*/
#include "iostream"
#include "vector"
#include "string"
#include "list"
#include "deque"
#include "utility"
#include "map"
#include "set"
#include "fstream"
#include "sstream"
#include "algorithm"
#include "numeric"
#include "iterator"
#include "functional"
#include "typeinfo.h"
#include "memory"
using namespace std;
template < typename T >//输入参数T是迭代器类型。
typename T::value_type mostFre(T first, T last)
//注意这里的typename T::value_type 这是在模板内部定义指定类型
/*--------------------------------------------------------------------------------------------------------------------
这个程序中第一个关键的地方就是迭代器中有一个成员,就是value_type
vector< int > vec;vec中的元素是{0,1,2,3,4}。vector< int >::iterator::value_type a = vec[4];
-----------------------------------------------------------------------------------------------------------------------*/
{
allocator< typename T::value_type > alloc;//用于分配T::value_type类型内存的对象 alloc。
//分配内存用于保存输入序列的副本。
T::value_type * newFirst = alloc.allocate(last - first);//分配原始的构造内存以保存T::value_type类型的n=last-first个对象.
T::value_type * newLast = newFirst + ( last - first );
//将输入序列复制到新分配的内存空间
uninitialized_copy(first, last, newFirst);
//对副本序列进行排序,是的相同的值出现在相邻的位置。
sort(newFirst, newLast);
size_t maxOccu = 0,occu = 0;//最频繁的出现次数,当前值出现次数
T::value_type * preIter = newFirst;
T::value_type * maxOccuElemIt = newFirst;//指向当前值的前一个值,当前出现最频繁的值。
while ( newFirst != newLast )
{
if ( *newFirst != *preIter )
{
if (occu > maxOccu)
{
maxOccu = occu;
maxOccuElemIt = preIter;
}
occu = 0;
}
++occu;
preIter = newFirst;
++newFirst;
}
if ( occu > maxOccu)
{
maxOccu = occu;
maxOccuElemIt = preIter;
}
return *maxOccuElemIt;
}
int main()
{
int a[30] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5 };
vector< int > vec(a,a+30);
vector< int >::iterator iter_begin = vec.begin();
vector< int >::iterator iter_end = vec.end();
int Ncount = mostFre(iter_begin, iter_end);
cout <<"元素出现次数最多的元素是:"<<Ncount << endl;
string str = "hhhhhello!";
string::iterator it_begin = str.begin();
string::iterator it_end = str.end();
cout << "元素出现次数最多的元素是:" << mostFre(it_begin, it_end)<< endl;
/*----------------------------------------------------------------------------------------------------------------------------*/
allocator< int > alloc;
if ( typeid( vector< int >::iterator ) != typeid( alloc.allocate(iter_end - iter_begin) ) )
{
cout << " \n vector< int >::iterator 和 alloc.allocate(iter_end - iter_begin) 不是相同类型 \n " << endl;
}
if ( typeid(vector< int >::iterator::value_type *) == typeid(alloc.allocate(iter_end - iter_begin)) )
{
cout << " \n vector< int >::iterator::value_type 和 alloc.allocate(iter_end - iter_begin) 是相同类型 \n " << endl;
}
/*
注意这里也就是上面的mostFre()函数中,答案书上错误的地方。答案书上面写的是 T newFirst = alloc.allocate( last - first );
但是你真正编译程序的时候会出现大量的错误,其中最关键的一条就是:
错误1 error C2440: “初始化”: 无法从“int *”转换为“std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>”
本以为书上不会出现任何错误,但是问题出现了。
*/
/*----------------------------------------------------------------------------------------------------------------------------*/
return 0;
}
/*----------------------------------------------------------------------------------------------------------------
编写一个函数模板,这个函数模板,有一个类型模板形参和一个非类型模板形参。用来接收一个数组,并给这个数组赋值
-----------------------------------------------------------------------------------------------------------------*/
#include "iostream"
#include "vector"
#include "string"
#include "list"
#include "deque"
#include "utility"
#include "map"
#include "set"
#include "fstream"
#include "sstream"
#include "algorithm"
#include "numeric"
#include "iterator"
#include "functional"
#include "typeinfo.h"
#include "memory"
using namespace std;
template < typename T , size_t N >
void array_init( T (&parm) [N] )
{
for (size_t i = 0; i != N; ++i)
{
parm[i] = i;
cout << parm[i] << endl;
}
}
int main()
{
int a[10];
array_init(a);
double b[20];
array_init(b);
}
在《C++ Primer 第四版》的第七章中,讲到了通过引用传递数组,和其他类型一样,数组形参可声明为数组的引用。如果形参是数组的引用,编译器不会将数组实参转化为指针,而是传递数组的引用本身。在这种情况下,数组大小成为形参与实参类型的一部分,编译器检查数组实参的大小与形参的大小是否匹配。
#include <iostream>
using namespace std;
void output(int (&a)[5])//数组的引用作为函数的形参。
{
for(int i = 0; i < 5; i++)
cout<<a[i]<<endl;
}
int main()
{
int a[5]={0};
output(a);
getchar();
return 0;
}
#include <iostream>
using namespace std;
int main()
{
int a[5]={0};
int (&b)[5] = a;//直接声明一个数组的引用。
for(int i = 0; i < 5; i++)
cout<<b[i]<<endl;
cout<<sizeof(b);
getchar();
return 0;
}
你可以创建对数组的引用,但你不能创建一个元素都是引用的数组。
/*-------------------------------------------------------------------------------
编写一个函数模板,接受表示未知类型迭代器的一对值,找出在序列中出现得最频繁的值。
---------------------------------------------------------------------------------*/
#include "iostream"
#include "vector"
#include "string"
#include "list"
#include "deque"
#include "utility"
#include "map"
#include "set"
#include "fstream"
#include "sstream"
#include "algorithm"
#include "numeric"
#include "iterator"
#include "functional"
#include "typeinfo.h"
#include "memory"
using namespace std;
template <typename U>
int compare(U u1, U u2)
{
cout << "使用模板" << endl;
return 0;
}
int compare(int a, int b)
{
cout << "使用compare( int a,int b)函数" << endl;
return 0;
}
int main()
{
int a = 10, b = 20;
short s1 = 30, s2 = 40;
compare(s1, s2);//使用模板。并没有把short类型提升为int类型然后调用compare(int,int)
compare(a, b);//使用compare(int a, int b)函数,并没有调用函数模板。而是直接使用已经有的函数。
return 0;
}
/*-------------------------------------------------------------------------------
确定模板形参调用哪个函数。
---------------------------------------------------------------------------------*/
#include "iostream"
#include "vector"
#include "string"
#include "list"
#include "deque"
#include "utility"
#include "map"
#include "set"
#include "fstream"
#include "sstream"
#include "algorithm"
#include "numeric"
#include "iterator"
#include "functional"
#include "typeinfo.h"
#include "memory"
using namespace std;
template < typename T1> int compare(const T1&, const T1&)
{
if (typeid(T1)==typeid(int))
{
cout << "copare函数模板的实参是:int 类型 " << endl;
}
else if (typeid(T1)==typeid(string))
{
cout << "compare函数模板的实参是:string类型" << endl;
}
return 0;
}
void func(int(*p) (const string &, const string &))
{
string str1 = "hello", str2 = "world";
p(str1, str2);
cout << "void func(int(*) (const string &, const string &))" << endl;
}
void func(int(*p) (const int & , const int & ))
{
int a = 10;
int b = 20;
p(a, b);
cout << "void func(int(*) (const int &, const int &))" << endl;
}
int main()
{
func(compare);
/*错误 1 error C2668: “func”: 对重载函数的调用不明确。
因为有两个可以用来调用 一个是int 一个是string所以会产生冲突。
template < typename T1> int compare(const T1&, const T1&)
我们看这个模板,有一个模板形参 T1 而且compare()函数中的形参也只有一个T1
所以,我们就可以通过指定 T1 来指定调用哪个函数。
*/
func( compare<int> );
func(compare<string>);
return 0;
}
/*本程序是为了演示模板编译模型中的【包含编译模型】
这个文件是median.h头文件,这个头文件是模板的声明。*/
#ifndef _MEDIAN_H_
#define _MEDIAN_H_
//#include "vector"
//#include "algorithm" //这里有没有都没有问题。
using std::vector;
/*
如果这里不使用 using std::vector那么就会出错。
语法错误 : 缺少“,”(在“<”的前面)
*/
template < typename T >
bool median( const vector < T > & , T & );
#include "median.cpp"
#endif
/*这个cpp文件是median.cpp文件。其中的内容是模板的实现。注意在vs2013中这个实现文件千万不要添加到项目中,否则就会出现编译的问题。要把这个文件从项目中移出*/
template < typename T>
bool median( const vector<T> & t , T & tVal )
{
vector<T> temp(t);//临时的vector
if (0 == temp.size() % 2)
{
return false;
}
vector<T>::iterator iter_begin = temp.begin();
vector<T>::iterator iter_end = temp.begin();
sort(iter_begin, iter_end);
vector<T>::size_type mid = temp.size() / 2;
if (temp[mid] > temp[mid - 1] && temp[mid] < temp[mid + 1])
{
tVal = temp[mid];
return true;
}
else
{
return false;
}
}
/*-------------------------------------------------------------------------------
模板编译模型中的包含编译模型。主程序,用来调用模板。
---------------------------------------------------------------------------------*/
#include "iostream"
#include "vector"
#include "string"
#include "list"
#include "deque"
#include "utility"
#include "map"
#include "set"
#include "fstream"
#include "sstream"
#include "algorithm"
#include "numeric"
#include "iterator"
#include "functional"
#include "typeinfo.h"
#include "memory"
#include "median.h"
using namespace std;
int main()
{
int a[4] = { 1, 2, 3, 4 };
int a1[7] = { 1, 2, 3, 4, 5, 6, 7 };
int a2[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
vector<int> vec(a, a + 4);
int m=0;
median(vec, m);
cout << m << endl;
vector<int> vec1(a1, a1 + 7);
median(vec1, m);
cout << m << endl;
vector<int> vec2(a2, a2 + 9);
median(vec2, m);
cout << m << endl;
}
#include "iostream"//模板的特化操作的例子。模板特化的时候调用函数的次序。
#include "vector"
#include "string"
#include "list"
#include "deque"
#include "utility"
#include "map"
#include "set"
#include "fstream"
#include "sstream"
#include "algorithm"
#include "numeric"
#include "iterator"
#include "functional"
#include "typeinfo.h"
#include "memory"
using namespace std;
template < typename T> int compare(const T & t1, const T & t2)
{
cout << "调用的是:\n template < typename T> int compare(const T & t1, const T & t2)" << endl;
return 0;
}
//特化的模板函数
template <> int compare<const char *>(const char * const & t1, const char * const & t2)
{
cout << "调用的是特化的模板:\n int compare<const char *>(const char * const T & t1, const char * const T & t2)" << endl;
return 0;
}
int compare(const char * & t1, const char * & t2)
{/*注意有特化的const char *参数的函数 和 专门的const char * 函数。那么首先调用专门的函数。
如果没有专门的函数,那么才会调用特化的模板函数。*/
cout << "调用:\n int compare(const char * & t1, const char * & t2)" << endl;
return 0;
}
int main()
{
const char * c1 = "hello";
const char * c2 = "world";
compare(c1, c2);//注意这个函数的调用。
int a = 10, b = 20;
compare(a, b);
double c = 10.0, d = 20.0;
compare(c, d);
return 0;
}