C++模板——完全特化

Posted gzming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++模板——完全特化相关的知识,希望对你有一定的参考价值。

1. 简介

完全特化(full specialization)也叫显式特化(explict specialization). 它允许为给定的模板实参自定义模板代码.

2. 语法

template <> declaration

必须实例化所有的模板形参.

如,

#include <iostream>

template <typename T>
struct IsVoid
{
    static constexpr bool value = false;
};

template <>
struct IsVoid<void>
{
    static constexpr bool value = true;
};


int main()
{
    std::cout << std::boolalpha << IsVoid<int>::value << \'\\n\';        // false
    std::cout << std::boolalpha << IsVoid<void>::value << \'\\n\';        // true
}

3. 什么时候不需要加上 template <>?

(1)如果你正在显式特化一个模板,则应该加上 template <>.

template<class T> class Array { /*...*/ };

// primary template
template<class T> void sort(Array<T>& v);

// specialization for T = int
template<> void sort(Array<int>&);
template<typename T>
struct A {
    struct B {}
    template<class U> struct C { };
};

template <>
struct A<int> {
    void f(int);
};

(2)如果你正在为一个已显式特化的类模板定义成员,则不需要加上 template <>.

void A<int>::f(int) {}

此时 A<int> 已是一个具体的类,不再是模板,没有模板形参,不再是可以被特化的实体了.

(3)如果模板 A 之前没有被显式特化过,而你正在为 A<Type> 特化它的某个成员 B,则需要加上 template <>.

template<>
struct A<char>::B {
    void f();
};

(4)如果模板 A 之前没有被显式特化过,但已为 A<Type> 特化它的某个成员 B(非类模板),则在定义 B 的成员时,不需要加上 template <>.

void A<char>::B::f() {}

A<char>::B 已是具体的类型,不可特化.

(5)如果模板 A 之前没有被显式特化过,但已为 A<Type> 特化它的某个成员 C,且 C 是一个类模板,则在定义 C 的成员时,需要加上 template <>.

template<>
template<class U>
struct A<char>::C {
    void f();
};

template<>
template<class U>
void A<char>::C<U>::f() { /* ... */ }

(6)如果类模板的成员也是一个模板,也可以将其显式特化.

template<typename T>
struct A {
    template<class U> void g1(T, U);
};

template<>
template<>
void A<int>::g1(int, char);

template<>
template<>
void A<int>::g1(int, char) {}

(7)如果类模板 A 已显式特化,其成员 C 是一个类模板,则在显式特化 C 时,不需要加上 template <>.

template<typename T>
struct A {
    struct B {}
    template<class U> struct C { };
};

template <>
struct A<int> {
    template<class U> struct C { };
};

template <>
struct A<int>::C<char> {
    void f();
};

void A<int>::C<char>::f() {}

以上是关于C++模板——完全特化的主要内容,如果未能解决你的问题,请参考以下文章

C++ 函数模板部分特化?

C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)

仅针对一个索引的 C++ 方法模板特化

C++中模板类成员函数的特化

C++初阶第十三篇—模板进阶(非类型模板参数+模板特化+模板的分离编译)

C++ template —— 模板特化