C++模板特化

一 、“函数模板”与“模板函数”

下面几行代码就是一个“函数模板”

template <class T>

T abs(T x)

{

    return x < 0 ? -x : x;

}

根据“函数模板”可以生成不同的函数,这些“实例化”的函数被称之为“模板函数”。

如:abs(0.1f);  编译器将根据函数模板生成模板函数abs<float> ,并调用abs<float>(0.1f)

如:abs(0.1);   编译器将根据函数模板生成模板函数abs<double>,并调用abs<double>(0.1)

二、函数模板的特例化

template <>

const char* abs<const char*>(const char*s)

{

    if(s && s[0] == '-')

    {

        return s + 1;

    }

    return NULL;

}

代码 abs("-5") 将调用特化后的 abs<const char*> 函数。

三、函数模板的匹配

template <class T>

T abs(T x)

{

    return x < 0 ? -x : x;

}

 

int abs(int x)

{

    return x < 0 ? -x : x;

}

代码 abs(1) 将调用 abs,而不是模板函数 abs<int>,也就是说:非模板函数具有优先权

下面再考虑函数模板被特化后的匹配问题:增加如下代码

template <>

int abs<int>(int x)

{

    return x < 0 ? -x : x;

}

同样的代码 abs(1),将调用什么呢?答案是:不确定。具体来说,对于 VC++6.0 而言,abs

函数和模板函数 abs<int> 被当做同一函数,谁先定义谁就有效。对于 VC++2008 而言,abs

函数和模板函数 abs<int> 是两个函数,但 abs 的优先级高于 abs<int>。

总结:对于VC++2008而言,始终是非模板函数具有优先权。对于VC++6.0而言,函数模板被

特化时要特别小心。

四、 类模板与特化

下面是一个类模板的例子

template <class T1,class T2>

class CTest

{

public:

    T1 m_a;

    T2 m_b;

};

 

1、全特化

template <>

class CTest<int,double>

{

public:

    T1 m_a;    //编译器自动将 T1 替换为 int

    T2 m_b;    //编译器自动将 T2 替换为 double

};

2、偏特化(VC++6.0 至 VC++2003不支持偏特化)

template <class T1>

class CTest<T1,int>

{

public:

    T1  m_a;

    int m_b;  //这里不能再使用 T2

};

五、成员函数模板、模板成员函数、特化

class CTest

{

public:

    template<class T>

    T Add(T x) const

    {//成员函数模板

        return (T)m_a + x;

    };

public:

    int m_a;

};

CTest::Add 就是一个成员函数模板,编译器将根据不同的参数生成不同的模板成员函数。

下面是成员函数模板的特化:

class CTest

{

public:

    template<class T>

    T Add(T x) const

    {

        return (T)m_a + x;

    };

    template<>

    double Add<double>(double x) const

    {//这个就是特化后的成员函数

        return (double)m_a + x;

    };

public:

    int m_a;

};

VC++6.0 不允许特化成员函数模板的声明、定义分离,如下面的代码在 VC++6.0 里无法编译

class CTest

{

public:

    ...   ...   ...

    template<>

    double Add<double>(double x) const;   //特化函数声明

    ...   ...   ...

};

//特化函数实现

template<>

double CTest::Add<double>(double x) const;

{

    return (double)m_a + x;

};

posted @ 2016-12-12 14:35  hanford  阅读(714)  评论(0编辑  收藏  举报