在线文档教程
C++
语言 | Language

explicit template specialization

显式%28%29模板专门化

允许为给定的一组模板参数自定义模板代码。

句法

template <> declaration

下列任何一项都可以完全专门化:

  • 功能模板

  • 类模板

  • %28自C++14%29可变模板

  • 成员函数类模板的

  • 静态数据成员类模板的

  • 成员类类模板的

  • 成员枚举类模板的

  • 成员类模板类或类模板的

  • 成员函数模板类或类模板的

例如,

二次

#include <iostream> template<typename T> // primary template struct is_void : std::false_type { }; template<> // explicit specialization for T = void struct is_void<void> : std::true_type { }; int main() { // for any type T other than void, the // class is derived from false_type std::cout << is_void<char>::value << '\n'; // but when T is void, the class is derived // from true_type std::cout << is_void<void>::value << '\n'; }

二次

详细

显式专门化可以在主模板定义为%28的任何作用域中声明,这可能与定义主模板的作用域不同,例如成员模板29%。显式专门化必须出现在非专门化模板声明之后。

二次

namespace N { template<class T> class X { /*...*/ }; // primary template template<> class X<int> { /*...*/ }; // specialization in same namespace template<class T> class Y { /*...*/ }; // primary template template<> class Y<double>; // forward declare specialization for double } template<> class N::Y<double> { /*...*/ }; // OK: specialization in same namespace

二次

必须在第一次使用之前声明专门化,这将导致隐式实例化,在发生这种使用的每个翻译单元中:

二次

class String {}; template<class T> class Array { /*...*/ }; template<class T> void sort(Array<T>& v) { /*...*/ } // primary template void f(Array<String>& v) { sort(v // implicitly instantiates sort(Array<String>&), } // using the primary template for sort() template<> // ERROR: explicit specialization of sort(Array<String>) void sort<String>(Array<String>& v // after implicit instantiation

二次

已声明但未定义的模板专门化可与任何其他专门化操作一样使用。不完全类型%28等。指针和对它的引用可以使用%29。

二次

template<class T> class X; // primary template template<> class X<int>; // specialization (declared, not defined) X<int>* p; // OK: pointer to incomplete type X<int> x; // error: object of incomplete type

二次

函数模板的显式专门化

在对函数模板进行专门化时,如果模板参数推导可以通过函数参数提供它们:

二次

template<class T> class Array { /*...*/ }; template<class T> void sort(Array<T>& v // primary template template<> void sort(Array<int>& // specialization for T = int // no need to write // template<> void sort<int>(Array<int>&

二次

具有与专门化相同的名称和参数列表的函数不是专门化%28(见功能[医]模板29%。

函数模板的显式专门化只有在使用内联说明符%28或定义为已删除的%29,如果主模板是内联的,则%27T不重要。

默认函数参数当类被隐式实例化时,不能在函数模板、成员函数模板和类模板的成员函数的显式专门化中指定。

显式专门化不能是朋友声明...

如果主模板具有%27T的异常规范noexcept(false),显式专门化必须具有兼容的异常规范。

专业成员

在类主体之外定义显式专门化类模板的成员时,语法template <>不使用,除非它%27是显式专门化成员类模板的成员,该成员模板是作为类模板专门化的,否则,语法将需要这样的定义。template<parameters>嵌套模板所需。

二次

template< typename T> struct A { struct B {}; // member class template<class U> struct C { }; // member class template }; template<> // specialization struct A<int> { void f(int // member function of a specialization }; // template<> not used for a member of a specialization void A<int>::f(int) { /* ... */ } template<> // specialization of a member class struct A<char>::B { void f( }; // template<> not used for a member of a specialized member class either void A<char>::B::f() { /* ... */ } template<> // specialization of a member class template template<class U> struct A<char>::C { void f( }; // template<> is used when defining a member of an explicitly // specialized member class template specialized as a class template template<> template<class U> void A<char>::C<U>::f() { /* ... */ }

二次

如果声明包含初始化程序,则模板的静态数据成员的显式专门化是定义;否则,则为声明。这些定义必须使用大括号进行默认初始化:

二次

template<> X Q<int>::x; // declaration of a static member template<> X Q<int>::x ( // error: function declaration template<> X Q<int>::x {}; // definition of a default-initialized static member

二次

类模板的成员或成员模板可以显式地专门化为类模板的给定隐式实例化,即使在类模板定义中定义了成员或成员模板。

二次

template<typename T> struct A { void f(T // member, declared in the primary template void h(T) {} // member, defined in the primary template template<class X1> void g1(T, X1 // member template template<class X2> void g2(T, X2 // member template }; // specialization of a member template<> void A<int>::f(int // member specialization OK even if defined in-class template<> void A<int>::h(int) {} // out of class member template definition template<class T> template<class X1> void A<T>::g1(T, X1) { } // member template specialization template<> template<class X1> void A<int>::g1(int, X1 // member template specialization template<> template<> void A<int>::g2<char>(int, char // for X2 = char // same, using template argument deduction (X1 = char) template<> template<> void A<int>::g1(int, char

二次

成员或成员模板可以嵌套在许多封装类模板中。在该成员的显式专门化中,有%27 s atemplate<>对于每个显式专门化的封闭类模板。

二次

template<class T1> class A { template<class T2> class B { void mf( }; }; template<> template<> class A<int>::B<double>; template<> template<> void A<char>::B<char>::mf(

二次

在这样的嵌套声明中,一些级别可能仍然是非专用%28,除非它可以在封装类为非专用%29的情况下专门化类成员模板。对于每个级别,声明都需要template<arguments>,因为这些专门化本身就是模板:

二次

template <class T1> class A { template<class T2> class B { template<class T3> void mf1(T3 // member template void mf2( // non-template member }; }; // specialization template<> // for the specialized A template<class X> // for the unspecialized B class A<int>::B { template <class T> void mf1(T }; // specialization template<> // for the specialized A template<> // for the specialized B template<class T> // for the unspecialized mf1 void A<int>::B<double>::mf1(T t) { } // ERROR: B<double> is specialized and is a member template, so its enclosing A // must be specialized also template<class Y> template<> void A<Y>::B<double>::mf2() { }

二次

缺陷报告

以下行为更改缺陷报告追溯应用于先前发布的C++标准。

DRApplied toBehavior as publishedCorrect behavior
CWG 727C++14full specializations not allowed in class scope, even though partial arefull specialization allowed in any scope

另见

  • 模板

  • 类模板

  • 功能模板

  • 部分专业化

© cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

http://en.cppreference.com/w/cpp/language/Template[医]专业化