STL: 模板特例化

      编写单一模板的时候,使之对任何可能的模板参数都是最合适的,都能实例化, 这并不总是能办到的.在某些情况下,通用模板的定义对特定类型可能是并不合适的,通用定义可能编译失败。其他时候我们也可以利用特例化来编写更加高效的代码.

特例化的本质是实例化一个模板,而不是重载它!因此特例化不影响匹配.

我们从两个方面来讨论:

1, 函数特例化.

当定义函数模板特例化的时候,我们本质上接管了编译器的工作。即,我们为原模板的一个特殊实例提供了定义。重要的是:一个特例化版本本质上是一个实例,而不是一个重载! 而且函数模板是不能部分特例化的!

#include <iostream>


template<typename Ty>
bool compare(const Ty& lh, const Ty& rh)
{
	std::cout << "the base version!" << std::endl;
	return (lh > rh);
}

//特例化版本
//注意下面的参数类型为什么是 const char* const&
//由于是特例化因此我们必须保持与原函数的类型匹配.
//也就是说: 我们特例化的实际上是Ty, 但是Ty前面后面的限定符号和关键字必须保存(也就是说const 和 & 必须保存)!
template<>
bool compare(const char* const& lh, const char* const& rh)
{
	std::cout << "the specialized version" << std::endl;
	return std::strcmp(lh, rh);
}

int main()
{
	//case 1:
	std::cout << std::boolalpha << compare(10, 20) << std::endl;

	//case 2:
	const char* str1{ "shihua" };
	const char* str2{ "marryme" };
	std::cout << std::boolalpha << compare(str1, str2) << std::endl;

	return 0;
}

 

 

2.0, class特例化.

#include <iostream>

template<typename Ty>
class Test {
private:
	Ty data;

public:
	Test(const Ty& val) :data{ val } {}
	Test(const Test<Ty>& other) = default;
	Test(Test<Ty>&& other) = default;
	Test<Ty>& operator=(const Test<Ty>& other) = default;
	Test<Ty>& operator=(Test<Ty>&& other) = default;

	~Test() {}
	
	void print()const
	{
		std::cout << data << std::endl;
	}
};

//case 1:  部分特例化.
template<>
void Test<int>::print()const
{
	std::cout << "case 1" << std::endl;
}

//case 2: 部分特例化的另外一种情况.
template<typename Ty>
class Test<Ty&> {
private:
	Ty data;

public:
	Test(const Ty& val) :data{ val } {}
	Test(const Test<Ty&>& other) = default;
	Test(Test<Ty&>&& other) = default;
	Test<Ty&>& operator=(const Test<Ty&>& other) = default;
	Test<Ty&>& operator=(Test<Ty&>&& other) = default;

	~Test() {}

	void print()const
	{
		std::cout << "case 2" << std::endl;
	}
};


//case 3: 全特例化.
template<>
class Test<char> {
private:
	char data;

public:
	Test(const char& val) :data{ val } {}
	Test(const Test<char>& other) = default;
	Test(Test<char>&& other) = default;
	Test<char>& operator=(const Test<char>& other) = default;
	Test<char>& operator=(Test<char>&& other) = default;

	~Test() {}

	void print()const
	{
		std::cout << "case 3"<< std::endl;
	}
};

int main()
{
	Test<long> t1{ 100 };
	t1.print();

	//case 1:
	Test<int> t2{ 100 };
	t2.print();

	//case 2:
	Test<int&> t3{ 100 };
	t3.print();

	//case 3:
	Test<char> t4{ 'p' };
	t4.print();

	return 0;
}

 

2.1: class特例化

#include <iostream>
#include <cstdio>
#include <sstream>


template<typename Ty1>
struct Test;

template<>
struct Test<int>
{
	Test(const int& value)noexcept
	{
		std::cout << value << std::endl;
	}
};


int main()
{
	Test<int> t1{ 10 };
	return 0;
}

2.1.1: class特例化.

#include <iostream>

template<typename ...>
struct test;

template<>
struct test<>
{
  int number_;  
};

template<typename Ty1_, typename Ty2_>
struct test<Ty1_, Ty2_>
{
    std::string str_;
};

int main()
{
    test<> the_test_{ 20 };
    test<int, bool> the_test_2{ "shihuamarryme" };
    std::cout << the_test_.number_ << std::endl;
    std::cout << the_test_2.str_ << std::endl;
    
    return 0;
}

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/850654

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值