<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[现代C++泛型编程初识 - 类模板到模板特例化及具体应用示例]]></title><description><![CDATA[<h2>文章导读</h2>
<ul>
<li>一、类模板与模板特化(全特化与偏特化)</li>
<li>二、类模板与其模板特化的应用</li>
<li>三、模板特化存在性问题</li>
</ul>
<h2>一、类模板与模板特化(全特化与偏特化)</h2>
<blockquote>
<p dir="auto">从接受类型的角度<br />
类模板：全集R<br />
模板偏特化(部分特化)：为全集的一个子集A<br />
模板全特化：为R中的一个"点"，或者说为R中的一个元素<br />
匹配规则：越特化匹配优先级越高(见下面例子)</p>
</blockquote>
<p dir="auto"><img src="/assets/uploads/files/1765188484753-98a9da6a-01af-4fc4-83ad-91b7ca549699-image.png" alt="98a9da6a-01af-4fc4-83ad-91b7ca549699-image.png" class=" img-fluid img-markdown" /></p>
<h3>1.类模板</h3>
<blockquote>
<p dir="auto">可以接受任意类型</p>
</blockquote>
<pre><code>// R
template&lt;typename T&gt;
class A {};    // 类模板是能接受任意类型，A后面不需要(不能)任何处理
</code></pre>
<h3>2.模板偏特化(局部特化)</h3>
<blockquote>
<p dir="auto">可以接受任意指针类型</p>
</blockquote>
<pre><code>// A
template&lt;typename T&gt;
class A&lt;T *&gt; {};    // 类模板A的偏特化版本，在A后指出特化的范围
</code></pre>
<h3>3.模板全特化</h3>
<blockquote>
<p dir="auto">指定接受int类型</p>
</blockquote>
<pre><code>template&lt;&gt;
class A&lt;int&gt; {}    // 类模板A的全特化版本(已经是类模板的一个实例了)，在A后直接指出明确类型int
</code></pre>
<h3>4.例子：</h3>
<pre><code>#include &lt;iostream&gt;
#include &lt;string&gt;

using namespace std;

template&lt;typename T&gt;
class A {
public:
    A() {
	cout &lt;&lt; "R" &lt;&lt; endl;
    }
};

/* 注释1　－－　接受指针
template&lt;typename T&gt;
class A&lt;T *&gt; {
public:
    A() {
	cout &lt;&lt; "A" &lt;&lt; endl;
    }
};
*/

/* 注释2　－－　接受int
template&lt;&gt;
class A&lt;int&gt; {
public:
    A() {
	cout &lt;&lt; "int" &lt;&lt; endl;
    }
};
*/

int main() {
    A&lt;string&gt; r;    // 1
    A&lt;char *&gt; a;    // 2
    A&lt;int&gt; i;       // 3
    return 0;
}
</code></pre>
<h3>5.测试不同情况:</h3>
<blockquote>
<p dir="auto">当只有一个类模板(可接受任意类型R)存在时，1, ２,  3都使用类模板实例化</p>
</blockquote>
<p dir="auto"><img src="/assets/uploads/files/1765188632617-v2-a53836d6d2a913d69c2fd90b0dd4371f_1440w.png" alt="v2-a53836d6d2a913d69c2fd90b0dd4371f_1440w.png" class=" img-fluid img-markdown" /></p>
<blockquote>
<p dir="auto">注释１是接受所以指针类型(R的子集A),所以称其为类模板A的偏特化(范围特化)。即把类模版A所能接受的指针类型单独处理(实例化)。当取消注释１时：char * 将由这个模板类A的偏特化版本(范围特化，局部特化)处理。</p>
</blockquote>
<p dir="auto"><img src="/assets/uploads/files/1765188640018-v2-2bd02b7f6a4dbb5cdbc586f98d76b92b_1440w.png" alt="v2-2bd02b7f6a4dbb5cdbc586f98d76b92b_1440w.png" class=" img-fluid img-markdown" /></p>
<blockquote>
<p dir="auto">注释２只接受int类型的参数(可以看出是全局R中的一个元素)。当你用int实例化A时，将会由这个全特化版本来实现(而不会使用可以接受任意类型的版本(泛化版))。</p>
</blockquote>
<p dir="auto"><img src="/assets/uploads/files/1765188702892-v2-6a08120bfe6da8471d8fb374b2665a65_1440w.png" alt="v2-6a08120bfe6da8471d8fb374b2665a65_1440w.png" class=" img-fluid img-markdown" /></p>
<h2>二、类模板与其模板特化的应用</h2>
<pre><code>用模板的偏特化　实现一个　能移除任意类型const属性的模板类：remove_const
主要功能和用法：
功能：
给remove_const一个类型后
－－１．(情况１)如果这个类型没有const属性则获得这个类型本身。
－－２．(情况２)如果这个类型有const属性则移除它。
用法：
remove_const&lt;Type&gt;::type
使用场景：
当拿到一个未知变量时，想获得这个变量(或对象)的非const的类型
</code></pre>
<h3>1.实现情况１</h3>
<blockquote>
<p dir="auto">似乎没做什么事，aa是int符合情况１。但情况２不符合，bb没有变成int。</p>
</blockquote>
<pre><code>#include &lt;iostream&gt;
#include &lt;type_traits&gt;

template&lt;typename T&gt;
struct remove_const {
    using type = T;
};


int main() {
    int a = 1;
    const int b = 2;
    remove_const&lt;decltype(a)&gt;::type aa = 3;
    remove_const&lt;decltype(b)&gt;::type bb = 4;
    std::cout &lt;&lt; std::is_same&lt;decltype(aa), int&gt;::value &lt;&lt; std::endl;
    std::cout &lt;&lt; std::is_same&lt;decltype(bb), int&gt;::value &lt;&lt; std::endl;
    return 0;
}
</code></pre>
<p dir="auto">运行结果:<br />
<img src="/assets/uploads/files/1765188812524-v2-7a36de2df8473699ecc173f27351c876_1440w.png" alt="v2-7a36de2df8473699ecc173f27351c876_1440w.png" class=" img-fluid img-markdown" /></p>
<h3>2.实现情况2</h3>
<p dir="auto">从上面的实现可以看出，当传给模板的参数是带const类型时它还会返回带const属性的类型。同时从remove_const的定义也可以看出他是个　复读机　你给他什么类型他就给你什么类型。</p>
<p dir="auto">这时候可以使用上面介绍的偏特化的性质，来把带有带const的类型这个子集从全集中分离出来　特殊处理。如下：</p>
<pre><code>#include &lt;iostream&gt;
#include &lt;type_traits&gt;

template&lt;typename T&gt;
struct remove_const {
    using type = T;
};

template&lt;typename T&gt;
struct remove_const&lt;const T&gt; {
    using type = T;
};

int main() {
    int a = 1;
    const int b = 2;
    remove_const&lt;decltype(a)&gt;::type aa = 3;
    remove_const&lt;decltype(b)&gt;::type bb = 4;
    std::cout &lt;&lt; std::is_same&lt;decltype(aa), int&gt;::value &lt;&lt; std::endl;
    std::cout &lt;&lt; std::is_same&lt;decltype(bb), int&gt;::value &lt;&lt; std::endl;
    return 0;
}
</code></pre>
<p dir="auto">运行结果:</p>
<blockquote>
<p dir="auto">给带const的类型，写了一个特化版本。所以当remove_const接受一个带const的类型时，就会通过这个偏特化版本实例化，由于这个偏特化版本把const从类型中分离出来了，则这里的T就是没有const的类型，从而实现去除类型const的功能。</p>
</blockquote>
<p dir="auto"><img src="/assets/uploads/files/1765188887344-v2-d337e4dc338fc9a90fcfa7ef9db27804_1440w.png" alt="v2-d337e4dc338fc9a90fcfa7ef9db27804_1440w.png" class=" img-fluid img-markdown" /></p>
<h2>三、模板特化存在性问题</h2>
<p dir="auto">一个类模板的特化，是对某一个类模板的子集做特化处理的。而它不能"独立存在"。既只有存在一个类模板X, 才能存在对它特化的版本。</p>
<pre><code>template&lt;typename T&gt;
class A&lt;T *&gt; {};

int main() { return 0; }
</code></pre>
<p dir="auto"><img src="/assets/uploads/files/1765188925072-v2-1023f2d6ec20e5efa6300629068527d6_1440w.png" alt="v2-1023f2d6ec20e5efa6300629068527d6_1440w.png" class=" img-fluid img-markdown" /></p>
]]></description><link>http://forum.d2learn.org/topic/151/现代c-泛型编程初识-类模板到模板特例化及具体应用示例</link><generator>RSS for Node</generator><lastBuildDate>Wed, 12 Aug 2026 02:14:08 GMT</lastBuildDate><atom:link href="http://forum.d2learn.org/topic/151.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 08 Dec 2025 10:16:16 GMT</pubDate><ttl>60</ttl></channel></rss>