Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Template parameters

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

      Everytemplate is parameterized by one or more template parameters.

      Each parameter intemplate-parameter-list (seetemplate declaration syntax) belongs to one of the following categories:

      • constant template parameter
      • type template parameter
      • template template parameter

      Contents

      [edit]Constant template parameter

      Also known asnon-type template parameter (seebelow).

      typename (optional) (1)
      typename (optional)=default (2)
      type...name (optional) (3)(since C++11)
      type - one of the following types:
      • a structural type (see below)
      (since C++17)
      (since C++20)
      name - the name of the constant template parameter
      default - thedefault template argument
      1) A constant template parameter.
      2) A constant template parameter with a default template argument.
      3) A constant templateparameter pack.


      Astructural type is one of the following types (optionally cv-qualified, the qualifiers are ignored):

      (since C++11)
      • all base classes and non-static data members are public and non-mutable and
      • the types of all base classes and non-static data members are structural types or (possibly multi-dimensional) array thereof.
      (since C++20)

      Array and function types may be written in a template declaration, but they are automatically replaced by pointer to object and pointer to function as appropriate.

      When the name of a constant template parameter is used in an expression within the body of the class template, it is an unmodifiableprvalue unless its type was an lvalue reference type, or unless its type is a class type(since C++20).

      A template parameter of the formclass Foo is not an unnamed constant template parameter of typeFoo, even if otherwiseclass Foo is anelaborated type specifier andclass Foo x; declaresx to be of typeFoo.

      Anidentifier that names a constant template parameter of class typeT denotes a static storage duration object of typeconst T, called atemplate parameter object, which isTemplate argument equivalence to the corresponding template argument after it has been converted to the type of the template parameter. No two template parameter objects are template-argument-equivalent.

      struct A{friendbool operator==(const A&,const A&)=default;}; template<A a>void f(){&a;// OKconst A& ra= a,&rb= a;// Both bound to the same template parameter objectassert(&ra==&rb);// passes}
      (since C++20)

      [edit]Type template parameter

      type-parameter-keyname (optional) (1)
      type-parameter-keyname (optional)=default (2)
      type-parameter-key...name (optional) (3)(since C++11)
      type-constraintname (optional) (4)(since C++20)
      type-constraintname (optional)=default (5)(since C++20)
      type-constraint...name (optional) (6)(since C++20)
      type-parameter-key - eithertypename orclass. There is no difference between these keywords in a type template parameter declaration
      type-constraint - either the name of aconcept or the name of a concept followed by a list of template arguments (in angle brackets). Either way, the concept name may be optionally qualified
      name - the name of the type template parameter
      default - thedefault template argument
      1) A type template parameter without a default.
      template<class T>class My_vector{/* ... */};
      2) A type template parameter with a default.
      template<class T=void>struct My_op_functor{/* ... */};
      3) A type templateparameter pack.
      template<typename...Ts>class My_tuple{/* ... */};
      4) A constrained type template parameter without a default.
      template<My_concept T>class My_constrained_vector{/* ... */};
      5) A constrained type template parameter with a default.
      template<My_concept T=void>class My_constrained_op_functor{/* ... */};
      6) A constrained type templateparameter pack.
      template<My_concept...Ts>class My_constrained_tuple{/* ... */};


      The name of the parameter is optional:

      // Declarations of the templates shown above:template<class>class My_vector;template<class=void>struct My_op_functor;template<typename...>class My_tuple;

      In the body of the template declaration, the name of a type parameter is a typedef-name which aliases the type supplied when the template is instantiated.

      Each constrained parameterP whosetype-constraint is Q designating the conceptC introduces aconstraint-expressionE according to the following rules:

      • ifQ isC (without an argument list),
      • ifP is not a parameter pack,E is simplyC<P>
      • otherwise,P is a parameter pack,E is a fold-expression(C<P> && ...)
      • ifQ isC<A1,A2...,AN>, thenE isC<P,A1,A2,...AN> or(C<P,A1,A2,...AN> && ...), respectively.
      template<typename T>concept C1=true;template<typename...Ts>// variadic conceptconcept C2=true;template<typename T,typename U>concept C3=true; template<C1 T>struct s1;// constraint-expression is C1<T>template<C1...T>struct s2;// constraint-expression is (C1<T> && ...)template<C2...T>struct s3;// constraint-expression is (C2<T> && ...)template<C3<int> T>struct s4;// constraint-expression is C3<T, int>template<C3<int>...T>struct s5;// constraint-expression is (C3<T, int> && ...)
      (since C++20)

      [edit]Template template parameter

      template<parameter-list>type-parameter-keyname (optional) (1)
      template<parameter-list>type-parameter-keyname (optional)=default (2)
      template<parameter-list>type-parameter-key...name (optional) (3)(since C++11)
      type-parameter-key -classortypename(since C++17)
      1) A template template parameter with an optional name.
      2) A template template parameter with an optional name and a default.
      3) A template templateparameter pack with an optional name.


      In the body of the template declaration, the name of this parameter is a template-name (and needs arguments to be instantiated).

      template<typename T>class my_array{}; // two type template parameters and one template template parameter:template<typename K,typename V,template<typename>typename C= my_array>class Map{    C<K> key;    C<V> value;};

      [edit]Name resolution for template parameters

      The name of a template parameter is not allowed to be redeclared within its scope (including nested scopes). A template parameter is not allowed to have the same name as the template name.

      template<class T,int N>class Y{int T;// error: template parameter redeclaredvoid f(){char T;// error: template parameter redeclared}}; template<class X>class X;// error: template parameter redeclared

      In the definition of a member of a class template that appears outside of the class template definition, the name of a member of the class template hides the name of a template parameter of any enclosing class templates, but not a template parameter of the member if the member is a class or function template.

      template<class T>struct A{struct B{};typedefvoid C;void f(); template<class U>void g(U);}; template<class B>void A<B>::f(){    B b;// A's B, not the template parameter} template<class B>template<class C>void A<B>::g(C){    B b;// A's B, not the template parameter    C c;// the template parameter C, not A's C}

      In the definition of a member of a class template that appears outside of the namespace containing the class template definition, the name of a template parameter hides the name of a member of this namespace.

      namespace N{class C{}; template<class T>class B{void f(T);};} template<class C>void N::B<C>::f(C){    C b;// C is the template parameter, not N::C}

      In the definition of a class template or in the definition of a member of such a template that appears outside of the template definition, for each non-dependent base class, if the name of the base class or the name of a member of the base class is the same as the name of a template parameter, the base class name or member name hides the template parameter name.

      struct A{struct B{};int C;int Y;}; template<class B,class C>struct X: A{    B b;// A's B    C b;// error: A's C isn't a type name};

      [edit]Default template arguments

      Default template arguments are specified in the parameter lists after the= sign. Defaults can be specified for any kind of template parameter (type, constant, or template), but not to parameter packs(since C++11).

      If the default is specified for a template parameter of a primary class template, primary variable template,(since C++14) or alias template, each subsequent template parameter must have a default argument, except the very last one may be a template parameter pack(since C++11). In a function template, there are no restrictions on the parameters that follow a default, and a parameter pack may be followed by more type parameters only if they have defaults or can be deduced from the function arguments(since C++11).

      Default parameters are not allowed

      (until C++11)

      On a friend function template declaration, default template arguments are allowed only if the declaration is a definition, and no other declarations of this function appear in this translation unit.

      (since C++11)

      Default template arguments that appear in the declarations are merged similarly to default function arguments:

      template<typename T1,typename T2=int>class A;template<typename T1=int,typename T2>class A; // the above is the same as the following:template<typename T1=int,typename T2=int>class A;

      But the same parameter cannot be given default arguments twice in the same scope:

      template<typename T=int>class X;template<typename T=int>class X{};// error

      When parsing a default template argument for a constant template parameter, the first non-nested> is taken as the end of the template parameter list rather than a greater-than operator:

      template<int i=3>4>// syntax errorclass X{/* ... */}; template<int i=(3>4)>// OKclass Y{/* ... */};

      The template parameter lists of template template parameters can have their own default arguments, which are only in effect where the template template parameter itself is in scope:

      // class template, with a type template parameter with a defaulttemplate<typename T=float>struct B{}; // template template parameter T has a parameter list, which// consists of one type template parameter with a defaulttemplate<template<typename=float>typename T>struct A{void f();void g();}; // out-of-body member function template definitions template<template<typename TT>class T>void A<T>::f(){    T<> t;// error: TT has no default in scope} template<template<typename TT=char>class T>void A<T>::g(){    T<> t;// OK: t is T<char>}

      Member access for the names used in a default template parameter is checked at the declaration, not at the point of use:

      class B{}; template<typename T>class C{protected:typedef T TT;}; template<typename U,typename V=typename U::TT>class D:public U{}; D<C<B>>* d;// error: C::TT is protected

      The default template argument is implicitly instantiated when the value of that default argument is needed, except if the template is used to name a function:

      template<typename T,typename U=int>struct S{}; S<bool>* p;// The default argument for U is instantiated at this point// the type of p is S<bool, int>*
      (since C++14)

      [edit]Notes

      Before C++26, constant template parameter were called non-type template parameter in the standard wording. The terminology was changed byP2841R6 /PR#7587.

      In template parameters, type constraints could be used for both type and constant parameters, depending on whetherauto is present.

      template<typename>concept C=true; template<C,// type parameter         Cauto// constant parameter>struct S{}; S<int,0> s;


      (since C++20)
      Feature-test macroValueStdFeature
      __cpp_nontype_template_parameter_auto201606L(C++17)Declaringconstant template parameters withauto
      __cpp_nontype_template_args201411L(C++17)Allow constant evaluation for allconstant template arguments
      201911L(C++20)Class types and floating-point types inconstant template parameters

      [edit]Examples

      Run this code
      #include <array>#include <iostream>#include <numeric> // simple constant template parametertemplate<int N>struct S{int a[N];}; template<constchar*>struct S2{}; // complicated constant exampletemplate<char c,// integral typeint(&ra)[5],// lvalue reference to object (of array type)int(*pf)(int),// pointer to functionint(S<10>::*a)[10]// pointer to member object (of type int[10])>struct Complicated{// calls the function selected at compile time// and stores the result in the array selected at compile timevoid foo(char base){        ra[4]= pf(c- base);}}; //  S2<"fail"> s2;        // error: string literal cannot be usedchar okay[]="okay";// static object with linkage//  S2<&okay[0]> s3;      // error: array element has no linkage    S2<okay> s4;// works int a[5];int f(int n){return n;} // C++20: NTTP can be a literal class typetemplate<std::array arr>constexprauto sum(){returnstd::accumulate(arr.cbegin(), arr.cend(),0);} // C++20: class template arguments are deduced at the call sitestatic_assert(sum<std::array<double,8>{3,1,4,1,5,9,2,6}>()==31.0);// C++20: NTTP argument deduction and CTADstatic_assert(sum<std::array{2,7,1,8,2,8}>()==28); int main(){    S<10> s;// s.a is an array of 10 int    s.a[9]=4;     Complicated<'2', a, f,&S<10>::a> c;    c.foo('0'); std::cout<< s.a[9]<< a[4]<<'\n';}

      Output:

      42
      This section is incomplete
      Reason: more examples

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 184C++98whether the template parameters of template template
      parameters are allowed to have default arguments is unspecified
      specification added
      CWG 1922C++98it was unclear whether a class template whose name is an
      injected-class-name can use the default arguments in prior declarations
      allowed
      CWG 2032C++14for variable templates, there was no restriction on the template
      parameters after a template parameter with a default argument
      apply the same restriction
      as on class templates
      and alias templates
      CWG 2542C++20it was unclear whether the closure type is structuralit is not structural
      CWG 2845C++20the closure type was not structuralit is structural
      if capture-less
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/template_parameters&oldid=182766"

      [8]ページ先頭

      ©2009-2025 Movatter.jp