C++类模板的特化(三)
本文主要介绍类模板的特化、局部特化和缺省模板实参;
1.类模板的特化
类模板的特化(Class Template Specialization)是指为特定的模板参数提供自定义实现的过程。通过特化,我们可以针对某些特定的类型或条件提供不同的行为或实现;
如果需要特化一个类模板,需要特化该模板中的所有成员函数;
模板的特化注意事项:
需要将模板写成template <>
,并且需要指明特定的类型,下面示例需要特化std::string
的类型,成员函数按照正常的函数实现即可
template <>
class Stack <std::string>
{}
示例
/*
* @brief: class complates
* @complie: g++ -g *.cc -o d -std=c++11
* @autor: your name
* @date: 2023/08/22
*/
#include <iostream>
#include <vector>
#include <stdexcept>
template <class T>
class Stack
{
private:
std::vector<T> elems;
public:
void push(T const&);
void pop();
T top() const;
bool empty() const
{
return elems.empty();
}
int32_t getElemsSize() const
{
std::cout<<"not string size"<<std::endl;
return elems.size();
}
};
template <typename T>
void Stack<T>::push(T const& elem)
{
elems.push_back(elem);
}
template <typename T>
void Stack<T>::pop()
{
if(elems.empty())
{
throw std::out_of_range("empty stack");
}
elems.pop_back();
}
template <typename T>
T Stack<T>::top() const
{
if(elems.empty())
{
throw std::out_of_range("empty stack");
}
return elems.back();
}
//std::string
template <>
class Stack <std::string>
{
private:
std::vector<std::string> elems;
public:
void push(std::string const&);
void pop();
std::string top() const;
bool empty() const
{
return elems.empty();
}
int32_t getElemsSize() const
{
std::cout<<"string size"<<std::endl;
return elems.size();
}
};
void Stack<std::string>::push(std::string const& elem)
{
elems.push_back(elem);
}
void Stack<std::string>::pop()
{
if(elems.empty())
{
throw std::out_of_range("empty stack");
}
elems.pop_back();
}
std::string Stack<std::string>::top() const
{
if(elems.empty())
{
throw std::out_of_range("empty stack");
}
return elems.back();
}
int main(int argc, char* argv[])
{
Stack<int> int_stack;
int_stack.push(10);
int_stack.push(20);
int_stack.push(30);
std::cout<<int_stack.getElemsSize()<<std::endl;
//std::string
Stack<std::string> string_stack;
string_stack.push("class");
string_stack.push("int");
string_stack.push("int64");
string_stack.push("double");
string_stack.push("float");
std::cout<<string_stack.getElemsSize()<<std::endl;
return 0;
}
2. 类模板的局部特化
类模板的局部特化(Partial Class Template Specialization)是指针对模板参数的部分特化,只针对某些特定的条件进行自定义实现的过程。通过局部特化,我们可以为满足特定条件的模板参数提供不同的实现。
示例
/*
* @brief: class complates
* @complie: g++ -g *.cc -o d -std=c++11
* @autor: your name
* @date: 2023/08/22
*/
#include <iostream>
#include <vector>
#include <stdexcept>
#include <string>
//局部特化
template <typename T, typename U>
class MyClass
{
public:
void print() const
{
std::cout<<"typename and typename"<<std::endl;
}
};
template <typename T>
class MyClass<T, std::string>
{
public:
void print() const
{
std::cout<<"typename and string"<<std::endl;
}
};
template <typename T>
class MyClass<T, double>
{
public:
void print() const
{
std::cout<<"typename and double"<<std::endl;
}
};
int main(int argc, char* argv[])
{
MyClass<int, int> int_myclass;
int_myclass.print();
MyClass<int, std::string> string_myclass;
string_myclass.print();
MyClass<int, double> double_myclass;
double_myclass.print();
return 0;
}
输出
typename and typename
typename and string
typename and double
3. 缺省模版实参
在函数模板的时候,可以将模板的参数定位为缺省值;即支持默认,也支持指定,使用起来更加的方便;
示例
/*
* @brief: class complates
* @complie: g++ -g *.cc -o d -std=c++11
* @autor: your name
* @date: 2023/08/22
*/
#include <iostream>
#include <vector>
#include <deque>
#include <stdexcept>
#include <string>
//缺省模版参数
template <typename T, typename CONT = std::vector<T>>
class Stack
{
private:
CONT elems;
public:
void push(T const&);
void pop();
T top() const;
bool empty() const
{
return elems.empty();
}
int32_t getElemsSize() const
{
return elems.size();
}
};
template <typename T, typename CONT>
void Stack<T, CONT>::push(T const& elem)
{
elems.push_back(elem);
}
template <typename T, typename CONT>
void Stack<T, CONT>::pop()
{
if(elems.empty())
{
throw std::out_of_range("empty stack");
}
elems.pop_back();
}
template <typename T, typename CONT>
T Stack<T, CONT>::top() const
{
if(elems.empty())
{
throw std::out_of_range("empty stack");
}
return elems.back();
}
int main(int argc, char* argv[])
{
//使用默认值
Stack<int> int_stack;
int_stack.push(10);
int_stack.push(20);
int_stack.push(30);
std::cout<<int_stack.top()<<std::endl;
//赋值类型
Stack<double, std::deque<double>> double_stack;
double_stack.push(10.11);
double_stack.push(20.22);
double_stack.push(30.33);
std::cout<<double_stack.top()<<std::endl;
return 0;
}
输出
30
30.33