C++模板(全特化与部分特化)

文章通过示例介绍了如何在C++中使用模板类实现一个基于vector的stack,并展示了类模板的全特化和部分特化。全特化示例中,将mystack特化为处理std::string类型,而部分特化则特化为处理指针类型。文章强调了在定义特化模板时,需要先有泛型模板的存在,并且特化定义需放在泛型模板之前,否则会导致编译错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2.类模板

书中主要围绕通过一个现有的vector实现一个stack,读者需要关注的就是类成员函数实现时,也需要通过template<class T>来实现,具体代码如下:

#include<iostream>
#include <cstring>
#include <vector>
#include <cassert>
using namespace std;
template <class T>
class mystack
{
    public:
        void push(T const& elem);
        T const& top();
        void pop();
        bool empty();
        void printOn(std::ostream& strm) const
        {
            for (T const& elem : elementArr)
            {
                strm << elem <<endl;
            }
        }
    private:
        vector<T> elementArr;
};

template<class T>
void mystack<T>::push(T const& elem)
{
    elementArr.push_back(elem);

}

template<class T>
T const& mystack<T>::top()
{
    assert(!elementArr.empty());
    return elementArr.back();
}

template<class T>
void mystack<T>::pop()
{
    assert(!elementArr.empty());
    elementArr.pop_back();
}

template<class T>
bool mystack<T>::empty()
{
    return elementArr.empty();
}

int main()
{

    mystack<int> testStack;
    testStack.push(1);
    testStack.push(5);
    testStack.push(3);
    testStack.push(2);
    testStack.push(8);
    cout<<testStack.top()<<endl;
    testStack.printOn(std::cout);
}

类的全特化和部分特化
1 全特化

#include<iostream>
#include <cstring>
#include <vector>
#include <cassert>
#include <string>
using namespace std;

template <class T>
class mystack
{
    public:
        void push(T const& elem);
        T const& top();
        void pop();
        bool empty();
        void printOn(std::ostream& strm) const
        {
            for (T const& elem : elementArr)
            {
                strm << elem <<endl;
            }
        }
    private:
        vector<T> elementArr;
};

template<class T>
void mystack<T>::push(T const& elem)
{
    elementArr.push_back(elem);

}

template<class T>
T const& mystack<T>::top()
{
    assert(!elementArr.empty());
    return elementArr.back();
}

template<class T>
void mystack<T>::pop()
{
    assert(!elementArr.empty());
    elementArr.pop_back();
}

template<class T>
bool mystack<T>::empty()
{
    return elementArr.empty();
}
#endif

template<>
class mystack<std::string>
{
    public:
        void push(std::string const& elem);
        std::string const& top();
        void pop();
        bool empty();
        void printOn(std::ostream& strm) const
        {
            for (std::string const& elem : elementArr)
            {
                strm << elem <<endl;
            }
        }
    private:
        vector<std::string> elementArr;
};
void mystack<std::string>::push(std::string const& elem)
{
    elementArr.push_back(elem);

}
std::string const& mystack<std::string>::top()
{
    assert(!elementArr.empty());
    return elementArr.back();
}
void mystack<std::string>::pop()
{
    assert(!elementArr.empty());
    elementArr.pop_back();
}
bool mystack<std::string>::empty()
{
    return elementArr.empty();
}

int main()
{

    mystack<std::string> testStack;
    testStack.push("1");
    cout<<testStack.top()<<endl;
    testStack.printOn(std::cout);
}

上述代码是将mystack全特化为string类型,在实际写代码时,发现如果只有全特化的函数template<>
class mystack<std::string>,没有template <class T>class mystack,会存在编译问题,说明定义全特化的前提是存在泛型的模板函数,并且需要定义在全特化函数之前

|=== Build: Debug in 3432432423 (compiler: GNU GCC Compiler) ===|
D:\3432432423\main.cpp|56|error: 'mystack' is not a class template|
D:\3432432423\main.cpp|57|error: explicit specialization of non-template 'mystack'|
D:\3432432423\main.cpp|73|error: expected initializer before '<' token|
D:\3432432423\main.cpp|78|error: expected initializer before '<' token|
D:\3432432423\main.cpp|83|error: expected initializer before '<' token|
D:\3432432423\main.cpp|88|error: expected initializer before '<' token|
D:\3432432423\main.cpp||In function 'int main()':|
D:\3432432423\main.cpp|96|error: 'mystack' is not a template|
||=== Build failed: 7 error(s), 0 warning(s) (0 minute(s), 1 second(s)) ===|

2.部分特化(特化为指针)

#include<iostream>
#include <cstring>
#include <vector>
#include <cassert>
#include <string>
using namespace std;
template<typename T>
class Stack {
	private:
		std::vector<T> elems; // elements
	public:
		void push(T elem); // push element
		T pop(); // pop element
		T top() const; // return top element
		bool empty() const
		{ // return whether
			return elems.empty();
		}
};
template<typename T>
void Stack<T>::push (T elem)
{
	elems.push_back(elem); // append copy of passed elem
}
template<typename T>
T Stack<T>::pop ()
{
	assert(!elems.empty());
	T p = elems.back();
	elems.pop_back(); // remove last element
	return p; // and return it (unlike in the general case)
}
template<typename T>
T Stack<T>::top () const
{
	assert(!elems.empty());
	return elems.back(); // return copy of last element
}

// partial specialization of class Stack<> for pointers:
template<typename T>
class Stack<T*> {
	private:
		std::vector<T*> elems; // elements
	public:
		void push(T* elem); // push element
		T* pop(); // pop element
		T* top() const; // return top element
		bool empty() const
		{ // return whether
			return elems.empty();
		}
};
template<typename T>
void Stack<T*>::push (T* elem)
{
	elems.push_back(elem); // append copy of passed elem
}
template<typename T>
T* Stack<T*>::pop ()
{
	assert(!elems.empty());
	T* p = elems.back();
	elems.pop_back(); // remove last element
	return p; // and return it (unlike in the general case)
}
template<typename T>
T* Stack<T*>::top () const
{
	assert(!elems.empty());
	return elems.back(); // return copy of last element
}

int main()
{

    Stack<int*> ptrStk;
    ptrStk.push(new int(10));
    std::cout << *ptrStk.top() << endl;
}

其逻辑与全特化一致,在定义时,不能只定义部分特化的模板,否则会有编译报错。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值