C++类模板的三种特化

news/2024/6/29 12:01:53 标签: c++, iterator, 编译器, access, c, float
cle class="baidu_pl">
cle_content" class="article_content clearfix">
content_views" class="htmledit_views">   class="Apple-style-span" style="color: rgb(0, 0, 0); font-family: georgia; font-size: 13px; line-height: 20px; ">class="Apple-style-span" style="color: rgb(75, 75, 75); ">说起C++的模板及模板特化࿰c; 相信很多人都很熟悉 ࿰c;但是说到模板特化的几种类型࿰c;相信了解的人就不是很多。我这里归纳了针对一个模板参数的类模板特化的几种类型࿰c; 一是特化为绝对类型; 二是特化为引用࿰c;指针类型;三是特化为另外一个类模板。
class="post" style="border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); background-color: white; padding-top: 20px; padding-right: 20px; padding-bottom: 20px; padding-left: 20px; color: rgb(75, 75, 75); ">

 这里用一个简单的例子来说明这三种情况:

color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238); "> color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> general version color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> Compare
{
color: rgb(0, 0, 255); ">public color: rgb(0, 0, 0); ">:
    
color: rgb(0, 0, 255); ">static color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> IsEqual( color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); "> lh,  color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); "> rh)
    {
        
color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); "> lh  color: rgb(0, 0, 0); ">== color: rgb(0, 0, 0); "> rh;
    }
};

这是一个用于比较的类模板࿰c;里面可以有多种用于比较的函数࿰c; 以IsEqual为例。
 
一、特化为绝对类型
也就是说直接为某个特定类型做特化࿰c;这是我们最常见的一种特化方式࿰c; 如特化为float, double等

color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238); "> color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> specialize for float color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template color: rgb(0, 0, 0); "><> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
{
color: rgb(0, 0, 255); ">public color: rgb(0, 0, 0); ">:
    
color: rgb(0, 0, 255); ">static color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> IsEqual( color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); "> lh,  color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); "> rh)
    {
        
color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); "> abs(lh  color: rgb(0, 0, 0); ">- color: rgb(0, 0, 0); "> rh)  color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); "> 10e color: rgb(0, 0, 0); ">- color: rgb(0, 0, 0); ">3 color: rgb(0, 0, 0); ">;
    }
};

color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> specialize for double color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template color: rgb(0, 0, 0); "><> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">double color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
{
color: rgb(0, 0, 255); ">public color: rgb(0, 0, 0); ">:
    
color: rgb(0, 0, 255); ">static color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> IsEqual( color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">double color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); "> lh,  color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">double color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); "> rh)
    {
        
color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); "> abs(lh  color: rgb(0, 0, 0); ">- color: rgb(0, 0, 0); "> rh)  color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); "> 10e color: rgb(0, 0, 0); ">- color: rgb(0, 0, 0); ">6 color: rgb(0, 0, 0); ">;
    }
};


 
二、特化为引用࿰c;指针类型
这种特化我最初是在stl源码的的class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_traits特化中发现的࿰c; 如下:

color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238); "> color: rgb(0, 0, 0); ">template  color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> _Iterator color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">struct color: rgb(0, 0, 0); "> class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_traits {
  typedef typename _Iterator::class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_category class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_category;
  typedef typename _Iterator::value_type        value_type;
  typedef typename _Iterator::difference_type   difference_type;
  typedef typename _Iterator::pointer           pointer;
  typedef typename _Iterator::reference         reference;
};

color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> specialize for _Tp* color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template  color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> _Tp color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">struct color: rgb(0, 0, 0); "> class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_traits color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">_Tp color: rgb(0, 0, 0); ">*> color: rgb(0, 0, 0); "> {
  typedef random_class="tags" href="/tags/ACCESS.html" title=access>access_class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_tag class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_category;
  typedef _Tp                         value_type;
  typedef ptrdiff_t                   difference_type;
  typedef _Tp
color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); ">                        pointer;
  typedef _Tp
color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); ">                        reference;
};

color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> specialize for const _Tp* color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template  color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> _Tp color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">struct color: rgb(0, 0, 0); "> class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_traits color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> _Tp color: rgb(0, 0, 0); ">*> color: rgb(0, 0, 0); "> {
  typedef random_class="tags" href="/tags/ACCESS.html" title=access>access_class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_tag class="tags" href="/tags/ITERATOR.html" title=iterator>iterator_category;
  typedef _Tp                         value_type;
  typedef ptrdiff_t                   difference_type;
  typedef 
color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> _Tp color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); ">                  pointer;
  typedef 
color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> _Tp color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); ">                  reference;
};

 

 当然࿰c;除了T*, 我们也可以将T特化为 const T*, T&, const T&等࿰c;以下还是以T*为例:

color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238); "> color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> specialize for T* color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">*> color: rgb(0, 0, 0); ">
{
color: rgb(0, 0, 255); ">public color: rgb(0, 0, 0); ">:
    
color: rgb(0, 0, 255); ">static color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> IsEqual( color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); "> lh,  color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); "> rh)
    {
        
color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">::IsEqual( color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); ">lh,  color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); ">rh);
    }
};

这种特化其实是就不是一种绝对的特化࿰c; 它只是对类型做了某些限定࿰c;但仍然保留了其一定的模板性࿰c;这种特化给我们提供了极大的方便࿰c; 如这里࿰c; 我们就不需要对int*, float*, double*等等类型分别做特化了。

三、特化为另外一个类模板

这其实是第二种方式的扩展࿰c;其实也是对类型做了某种限定࿰c;而不是绝对化为某个具体类型࿰c;如下:

color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238); "> color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> specialize for vector<T> color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">vector color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
{
color: rgb(0, 0, 255); ">public color: rgb(0, 0, 0); ">:
    
color: rgb(0, 0, 255); ">static color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> IsEqual( color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> vector color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">>& color: rgb(0, 0, 0); "> lh,  color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> vector color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">>& color: rgb(0, 0, 0); "> rh)
    {
        
color: rgb(0, 0, 255); ">if color: rgb(0, 0, 0); ">(lh.size()  color: rgb(0, 0, 0); ">!= color: rgb(0, 0, 0); "> rh.size())  color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">false color: rgb(0, 0, 0); ">;
        
color: rgb(0, 0, 255); ">else color: rgb(0, 0, 0); ">
        {
            
color: rgb(0, 0, 255); ">for color: rgb(0, 0, 0); ">( color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); "> i  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">0 color: rgb(0, 0, 0); ">; i  color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); "> lh.size();  color: rgb(0, 0, 0); ">++ color: rgb(0, 0, 0); ">i)
            {
                
color: rgb(0, 0, 255); ">if color: rgb(0, 0, 0); ">(lh[i]  color: rgb(0, 0, 0); ">!= color: rgb(0, 0, 0); "> rh[i])  color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">false color: rgb(0, 0, 0); ">;
            }
        }
        
color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">true color: rgb(0, 0, 0); ">;
    }
};


这就把IsEqual的参数限定为一种vector类型࿰c; 但具体是vector<int>还是vector<float>࿰c; 我们可以不关心࿰c; 因为对于这两种类型࿰c;我们的处理方式是一样的࿰c;我们可以把这种方式称为“半特化”。

当然࿰c; 我们可以将其“半特化”为任何我们自定义的模板类类型:

color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238); "> color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> specialize for any template class type color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">template  color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> T1 color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); "> 
color: rgb(0, 0, 255); ">struct color: rgb(0, 0, 0); "> SpecializedType
{
    T1 x1;
    T1 x2;
};
template 
color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
color: rgb(0, 0, 255); ">class color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">SpecializedType color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">
{
color: rgb(0, 0, 255); ">public color: rgb(0, 0, 0); ">:
    
color: rgb(0, 0, 255); ">static color: rgb(0, 0, 0); ">  color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> IsEqual( color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> SpecializedType color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">>& color: rgb(0, 0, 0); "> lh,  color: rgb(0, 0, 255); ">const color: rgb(0, 0, 0); "> SpecializedType color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">>& color: rgb(0, 0, 0); "> rh)
    {
        
color: rgb(0, 0, 255); ">return color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">T color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">::IsEqual(lh.x1  color: rgb(0, 0, 0); ">+ color: rgb(0, 0, 0); "> lh.x2, rh.x1  color: rgb(0, 0, 0); ">+ color: rgb(0, 0, 0); "> rh.x2);
    }
};


 这就是三种类型的模板特化࿰c; 我们可以这么使用这个Compare类:

color: rgb(204, 204, 204); border-right-color: rgb(204, 204, 204); border-bottom-color: rgb(204, 204, 204); border-left-color: rgb(204, 204, 204); padding-top: 4px; padding-right: 5px; padding-bottom: 4px; padding-left: 4px; font-size: 13px; width: 98%; background-color: rgb(238, 238, 238); "> color: rgb(0, 0, 0); ">    color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> int color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">     color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); "> i1  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">10 color: rgb(0, 0, 0); ">;
    
color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); "> i2  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">10 color: rgb(0, 0, 0); ">;
    
color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> r1  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">::IsEqual(i1, i2);

    
color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> float color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">     color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); "> f1  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">10 color: rgb(0, 0, 0); ">;
    
color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); "> f2  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">10 color: rgb(0, 0, 0); ">;
    
color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> r2  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">::IsEqual(f1, f2);

    
color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> double color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">     color: rgb(0, 0, 255); ">double color: rgb(0, 0, 0); "> d1  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">10 color: rgb(0, 0, 0); ">;
    
color: rgb(0, 0, 255); ">double color: rgb(0, 0, 0); "> d2  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">10 color: rgb(0, 0, 0); ">;
    
color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> r3  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">double color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">::IsEqual(d1, d2);

    
color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> pointer color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">     color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); "> p1  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); ">i1;
    
color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); ">* color: rgb(0, 0, 0); "> p2  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">& color: rgb(0, 0, 0); ">i2;
    
color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> r4  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); ">*> color: rgb(0, 0, 0); ">::IsEqual(p1, p2);

    
color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> vector<T> color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">    vector color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); "> v1;
    v1.push_back(
color: rgb(0, 0, 0); ">1 color: rgb(0, 0, 0); ">);
    v1.push_back(
color: rgb(0, 0, 0); ">2 color: rgb(0, 0, 0); ">);

    vector
color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); "> v2;
    v2.push_back(
color: rgb(0, 0, 0); ">1 color: rgb(0, 0, 0); ">);
    v2.push_back(
color: rgb(0, 0, 0); ">2 color: rgb(0, 0, 0); ">);
    
color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> r5  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">vector color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">int color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">::IsEqual(v1, v2);

    
color: rgb(0, 128, 0); ">// color: rgb(0, 128, 0); "> custom template class  color: rgb(0, 128, 0); ">
color: rgb(0, 0, 0); ">    SpecializedType color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); "> s1  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> { color: rgb(0, 0, 0); ">10.1f color: rgb(0, 0, 0); ">, color: rgb(0, 0, 0); ">10.2f color: rgb(0, 0, 0); ">};
    SpecializedType
color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); "> s2  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> { color: rgb(0, 0, 0); ">10.3f color: rgb(0, 0, 0); ">, color: rgb(0, 0, 0); ">10.0f color: rgb(0, 0, 0); ">};
    
color: rgb(0, 0, 255); ">bool color: rgb(0, 0, 0); "> r6  color: rgb(0, 0, 0); ">= color: rgb(0, 0, 0); "> Compare color: rgb(0, 0, 0); ">< color: rgb(0, 0, 0); ">SpecializedType color: rgb(0, 0, 0); ">< color: rgb(0, 0, 255); ">float color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">  color: rgb(0, 0, 0); ">> color: rgb(0, 0, 0); ">::IsEqual(s1, s2);


注:感谢longshanks对于本文中"类模板"与"模板类"概念的澄清࿰c;已更正 (2007-7-16)
class="postDesc" style="color: rgb(48, 48, 48); margin-top: 10px; text-align: right; "> posted on 2007-07-04 21:40  SmartPtr 阅读(1963)  评论(10)   编辑  收藏  引用 所属分类:  06. 程序语言
c="http://www.cppblog.com/SmartPtr/aggbug/27496.html?webview=1" width="1" height="1" />
comment">
FeedBack:
class="feedbackNoItems" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++模板类的三种特化[未登录]
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-05 11:23 |  yong
第二和第三种实际上就是template的"偏特化"或叫"部分特化"。这个概念不是什么新鲜的东东~ 呵呵   回复   更多评论
ctl00_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl00_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++模板类的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-05 11:53 |  SmartPtr
从广义上来讲࿰c; 我觉得可以把这种情形归入模板偏特化。 
但是根据我们一般的理解࿰c;模板的偏特化是指需要根据模板的某些但不是全部的参数进行特化࿰c; 如下: 
template<class T1, class T2> 
class A 



template<class T1> 
class A<T1, int> 



说实话࿰c; 我第一次发现第二和第三种用法时࿰c; 还是觉得挺新鲜的࿰c;这到底是属于全特化还是偏特化࿰c; 我也说不清楚࿰c; 但这也不重要࿰c;只要我们知道有这种用法࿰c;能应用它就行了   回复   更多评论
ctl01_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl01_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++模板类的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-05 15:57 |  walkspeed
模板有两种特化࿰c;全特化和偏特化(局部特化)
模板函数只能全特化࿰c;没有偏特化(以后可能有)。
模板类是可以全特化和偏特化的。

全特化࿰c;就是模板中模板参数全被指定为确定的类型。
全特化也就是定义了一个全新的类型࿰c;全特化的类中的函数可以与模板类不一样。

偏特化࿰c;就是模板中的模板参数没有被全部确定࿰c;需要class="tags" href="/tags/BianYiQi.html" title=编译器>编译器在编译时进行确定。

在类型上加上const、&、*( cosnt int、int&、int*、等等)并没有产生新的类型。只是类型被修饰了。模板在编译时࿰c;可以得到这些修饰信息。

以上的2、3就是偏特化。   回复   更多评论
ctl02_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl02_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++模板类的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-05 16:03 |  walkspeed
模板的特化是非常有用的。它像一个在编译期的条件判断。当class="tags" href="/tags/BianYiQi.html" title=编译器>编译器在编译时找到了符合的特化实现࿰c;就会使用这个特化实现。这就叫class="tags" href="/tags/BianYiQi.html" title=编译器>编译器多态(或者叫静态多态)。这种东西对编写基础库是很有用的。这也就是为何c++的基础库大量使用了模板技术࿰c;而且大量使用了特化࿰c;特别是偏特化。

在泛型中࿰c;利用特化类得到类新的特性࿰c;以便找到最适合这种特性的实现。而这一切都是在编译时完成。   回复   更多评论
ctl03_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl03_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++模板类的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-05 17:30 |  SmartPtr
谢谢walkspeed的回复࿰c; 我想对于全特化和偏特化这么理解应该是正确的࿰c; 就是全特化后确定了一个真正的类型࿰c; 而偏特化后其实还是一个原类型࿰c; 这样的话࿰c; 以上2࿰c; 3的确属于偏特化。 
模板的运用的确很广࿰c;无论模板元编程中的将计算提前到class="tags" href="/tags/BianYiQi.html" title=编译器>编译器࿰c;还是class="tags" href="/tags/BianYiQi.html" title=编译器>编译器多态(或者叫静态多态)࿰c; 都是非常漂亮聪明的应用࿰c; 在<<Modern C++ Design>>有着极好的体现。   回复   更多评论
ctl04_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl04_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++模板类的三种特化[未登录]
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-16 16:11 |  longshanks
如果这样分的话࿰c;还应该有第四种特化: 
template<typename T1, typename T2> 
class X {...}; 

template<typename T> 
class X<T, int> {...}; 
以及2、3、4的混合 
template<typename T> 
class X<T, T*> {...} 
template<typename T> 
class X<vector<T>, T&> {...}; 
... 
更极端的࿰c;这样的特化是否该归为第5类呢: 
template<typename T> 
class Y; 
template<typename R, typename P1, typename P2> 
class Y<R (P1, P2)> {...};//针对带两个参数࿰c;有返回值的函数类型特化 

实际上࿰c;3仅仅是局部特化结合template-template parameter的一个应用。算不上一“种”特化。 
总的来说࿰c;还是C++标准中的分类更加清晰。 

另外࿰c;根据C++标准术语࿰c;应该是“类模板”(class template)࿰c;而不是“模板类”。一般认为࿰c;“模板类”是模板实例化(特化)后的类: 
vector<int>   回复   更多评论
ctl05_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl05_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++模板类的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-16 21:26 |  SmartPtr
to longshanks 

本文的目的其实并不是试图对C++的模板特化做一下全面的分类࿰c; 而是针对自己所遇到的࿰c;觉得比较有意思的࿰c;对于一个模板参数所能够做到的特化࿰c;并不想对C++中的全特化࿰c;偏特化有所混淆。当然࿰c;之间也得到了大家不少有价值的看法。尤其对于您所举的这个例子: 
template<typename T> 
class Y; 
template<typename R, typename P1, typename P2> 
class Y<R (P1, P2)> {...};//针对带两个参数࿰c;有返回值的函数类型特化 

是我之前所没有想到的࿰c;我只考虑了数据类型并没有考虑到函数类型࿰c;但是我想参考针对数据类型所做的分类࿰c;可以得到函数类型对应平行的分类。比如对于这个例子࿰c;应该可以理解为第三种:特化为另外一个类(函数)模板。 

PS: 
谢谢关于模板类࿰c;类模板概念的澄清࿰c;原文已修改   回复   更多评论
ctl06_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl06_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++类模板的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-19 14:11 |  shen126
template<class T> 
class Compare<T*> 

public
static bool IsEqual(const T* lh, const T* rh) 

return Compare<T>::IsEqual(*lh, *rh); 

}; 

int _tmain(int argc, _TCHAR* argv[]) 


system("pause"); 
return 0; 

----- 
为什么这段代码在VS2005里编译出错了呢࿰c;难道不支持࿰c;还是需要打开什么特殊开关符吗? 
   回复   更多评论
ctl07_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl07_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++类模板的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-19 14:12 |  shen126
Error 1 error C2143: syntax error : missing ';' before '<' e:/vs_projects/stltest1/stltest1/stltest1.cpp 7
   回复   更多评论
ctl08_DeleteLink" style="color: rgb(67, 113, 166); ">   ctl08_EditLink">
class="feedbackItem" style="margin-bottom: 0px; margin-top: 20px; line-height: 200%; ">
class="feedbackListTitle" style="position: absolute; padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 7px; font-size: 12px; color: black; "> #  re: C++类模板的三种特化
class="feedbackListSubtitle" style="background-color: white; padding-top: 5px; padding-bottom: 5px; padding-left: 5px; padding-right: 7px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-top-style: dotted; border-right-style: dotted; border-bottom-style: dotted; border-left-style: dotted; border-top-color: rgb(189, 205, 238); border-right-color: rgb(189, 205, 238); border-bottom-color: rgb(189, 205, 238); border-left-color: rgb(189, 205, 238); text-align: right; margin-bottom: 8px; font-size: 12px; color: black; "> 2007-07-20 01:03 |  SmartPtr
template<class T> 
class Compare<T*> 

public
static bool IsEqual(const T* lh, const T* rh) 

return Compare<T>::IsEqual(*lh, *rh); 

}; 
是模板特化࿰c; 你当然需要在之前定义其泛化版本 
cle>

http://www.niftyadmin.cn/n/1139158.html

相关文章

iPad浏览器打不开网页 服务器停止响应,ipad网络连接正常打不开网页怎么办

或者你可以改成静态的IP。3在左边选择“无线局域网”&#xff0c;查看右边是否显示为“169.254.x.x”&#xff1a;此问题简单的解决办法就是关闭再重开WIFI或直接强制电源home重启ipad&#xff1a;ipad网络连接正常打不开网页的解决方法1首先第一步就是要确认获取的IP是否正确&…

Bjarne Stroustrup 语录

Bjarne Stroustrup 语录&#xff1a;一、致读者1&#xff0e; 在编程序时&#xff0c;你是在为你针对某个问题的解决方案中的思想建立起一种具体表示。让程序的结构尽可能地直接反映这些思想&#xff1a;★.如果你能把“它”看成一个独立的概念&#xff0c;就把它做成一个类。★…

js 刷新页面但是不闪烁_Js历史

1 Js是为了赶上java的潮流 把名字从LiveScript改为JavaScript2 Js出现原因 最初的输入验证必须把表单数据发到服务端上才能验证 而最初的js是为了解决这个问题。3 Web浏览器只是js实现的可能的宿主环境之一&#xff0c;其他的环境还有AdobeFlash 和Node4 JavaScript包括三个部分…

typedef的四个用途和两个陷阱

用途一&#xff1a; 定义一种类型的别名&#xff0c;而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如&#xff1a; char* pa, pb; // 这多数不符合我们的意图&#xff0c;它只声明了一个指向字符变量的指针&#xff0c; // 和一个字符变量&#x…

权威dns服务器存储信息,权威域名服务器

权威域名服务器 内容精选换一换本帖最后由知足常乐于2017-11-2513:02编辑DNS的查询过程有两种类型&#xff1a;递归查询和迭代查询。递归查询用于主机向本地域名服务器的查询。主机向本地域名服务器发出请求时&#xff0c;如果本地域名无法给出查询域名的IP地址&#xff0c;那么…

wps底纹去不掉_OMG | 没有它,娜扎徐璐脸上的痘也去不掉

如果没有好的皮肤底子&#xff0c;又怎么敢画裸妆呢&#xff1f;娜扎一直以来就以高颜值&#xff0c;好皮肤而出圈&#xff0c;让同是90后的妹子的我一直是又酸又羡慕。这几年皮肤状态越来越好&#xff0c;高清镜头下的皮肤也看不出什么瑕疵&#xff0c;肤质更是清透光亮&#…

新浪服务器远程安装系统,搭建PXE远程安装服务器+实现Kickstart无人值守安装

(基于vsftpd提供YUM软件仓库&#xff0c;基于PXE方式实现网络安装&#xff0c;基于kickstart配置文件实现自动应答。)系统环境(本实验为RHEL6虚拟机环境操作)软件环境&#xff1a;vsftpd-2.2.2-6.el6_0.1.i686sysstat-9.0.4-18.el6.i686dhcp-4.1.1-19.P1.el6.i686tftp-server-0…

Xerces C++解析XML文档

前一阵子学习Xerces-C&#xff0b;&#xff0b;用于解析指定格式XML文档。在这里&#xff0c;把自己的学习经历和大家分享一下&#xff0c;在这里仅仅讲一些入门的知识&#xff0c;希望对大家有所帮助。 Xerces-C是什么&#xff1f; Xerces-C 的前身是 IBM 的 XML4C …