0
点赞
收藏
分享

微信扫一扫

C++可变模版(Variadic Template)与模版模版参数(Template Template Param)



文章目录

  • ​​1 概念​​
  • ​​2 模版模版参数​​

1 概念

​...​​​就是一个所谓的包,用于模版编程(​​template parameters​​​)就是模版参数包(​​template parameters pack​​​),用于函数参数(​​function paramter types​​​)就是函数参数类型包(​​function paramater types pack​​)。

1,可变模版函数的示例代码:

打印变量:

//不定量模版参数
#include <iostream>
#include<bitset>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

void print(){

}

template<typename T, typename...Types>
void print(const T& firstArg, const Types&... args){
std::cout<<firstArg<<std::endl;
print(args...);
}


int main(int argc, char** argv) {
// std::cout<<__cplusplus;
print(7.5, "hello", std::bitset<16>(377), 42);
return 0;
}

计算最大值:

int maxinum(int n){
return n;
}

template<typename... Args>
int maxinum(int n, Args... args){
return std::max(n, maxinum(args...));
}

int main(){
std::cout<<maxinum(1, 5, 10, 3, 2);
}

打印tuple

template<int IDX, int MAX, typename ... Args>
struct PRINT_TUPLE{//1
static void print(std::ostream& os, const std::tuple<Args...>&t){
os<<get<IDX>(t)<<(IDX + 1 == MAX ? "" : ", ");//get<IDX>(t):取出IDX,并将IDX+1
PRINT_TUPLE<IDX + 1, MAX, Args...>::print(os, t);
}
};

template<int MAX, typename ... Args>
struct PRINT_TUPLE<MAX, MAX, Args...>{//2
static void print(std::ostream& os, const std::tuple<Args...>&t){}
};

template<typename ... Args>
std::ostream& operator<<(std::ostream& os, const std::tuple<Args...>&t){
os<<"[";
PRINT_TUPLE<0, sizeof ...(Args), Args...>::print(os, t);
return os<<"]";
}

int main(){
std::cout<<std::make_tuple(7.5, std::string("wqer"), std::bitset<16>(377), 54);
}

2,可变模版类的示例代码:

#include <iostream>

class A{
public:
// template<typename... Args>
// A(Args&&... args, int a, int b){
//
// }
template<typename... Args>
A(int a, Args&&... args){

}

};

int main(){
A a(1, 2, 4);
return 0;
}

3,递归继承的示例代码:

//递归继承(recursive inheritance)
#include <iostream>
#include <string>
using std::string;
using std::cout;
using std::endl;

template <typename... Values>
class tuple;

template <>
class tuple<>{};

template <typename Head, typename... Tail>
class tuple<Head, Tail...>
:private tuple<Tail...>
{
typedef tuple<Tail...>inherited;
public:
tuple(){}
tuple(Head v, Tail... vtail)
:m_head(v),inherited(vtail...){}

//typename Head::type head(){return m_head;}
Head head(){return m_head;}
inherited& tail(){ return *this;}

protected:
Head m_head;
};

int main(){
tuple<int, float, string>t(41, 6.3, "nico");//41(继承于)--->6.3,"nico"(继承于)--->"nico"
cout<<t.head()<<endl;//41
//cout<<t.tail()<<endl;//6.3 "nico"
cout<<t.tail().head()<<endl;//6.3
cout<<t.tail().tail().head()<<endl;//"nico"
return 0;
}

4,泛化和特化的示例代码:

//泛化、特化
#include <iostream>
#include <string>

//特化
template<typename T>
void dealPrint(int i, const T& val){
std::cout<<val<<std::to_string(i)<<std::endl;//3
}

template<typename T>
void print(int i, const T& val){
dealPrint(i, val);//2
}

template<typename T, typename... Types>
void print(int i, const T&val, const Types&... args){
dealPrint(i, val);
print(i, args...);//1
}

//泛化
template<typename... Types>
void print(const Types&... args){
print(2, args...);//0
}

int main(){
// print(1, "jiangxueHan", 3.5);
print("hell", "word", "tempale", 2);
return 0;
}

2 模版模版参数

示例代码如下:


1,用于模版函数中(函数中使用模版的类型);
2,用于模版类中中(类中模版参数嵌套了模版);


#include <iostream>
#include <list>
using std::cout;

//template <typename Container, typename T>
//void test_moveable(Container cntr, T elem){
// typename Container<T> c;
// for(long i = 0;i < 10;++i){
// c.insert(c.end(), T());
// }
// output_static_data(T());
// Container<T> c1(c);
// Container<T> c2(std::move(c));
// c1.swap(c2);
//};


template <typename T>
void output_static_data(const T& obj){
std::cout<<obj<<std::endl;
}
//法一
template <typename Container>
void test_moveable(Container c){
typedef typename std::iterator_traits<typename Container::iterator>::value_type Valtype;
for(long i = 0;i < 10;++i){
c.insert(c.end(), Valtype());
}
output_static_data(*(c.begin()));
Container c1(c);
Container c2(std::move(c));
c1.swap(c2);
};

template <typename T>
using Lst = std::list<T, std::allocator<T>>;

//法二
template <typename T, template <class > class Container>
class XCls{
private:
Container<T> c;
public:
XCls(){
for(long i = i; i < 10;++i)
c.insert(c.end(), T());
output_static_data(T());
Container<T> c1(c);
Container<T> c2(std::move(c));
c1.swap(c2);
}
};



int main(){
//法1
test_moveable(std::list<int>());
//法2
//XCls<int, std::list>c1;
XCls<int, Lst> c1;

return 0;
}



举报

相关推荐

0 条评论