Chapter 3 Non-type template parameters: 3.3 Restrictions on non-type template parameters

3.3 Restrictions for Nontype Template Parameters

3.3 Restrictions on non-type template parameters

 

Note that nontype template parameters carry some restrictions. In general, they can

be only constant integral values (including enumerations), pointers to objects/functions/members, lvalue references to objects or functions, or std::nullptr_t (the type of nullptr).

Note that non-type template parameters are limited. Generally speaking, they can only be constant integers (including enumerations), pointers to objects / functions / members, lvalue references to objects or functions, or std :: nullptr_t (type of nullptr).

 

Floating-point numbers and class-type objects are not allowed as nontype template

parameters:

Floating point and class objects are not allowed as non-type template parameters:

template < double VAT> // ERROR: floating-point numbers cannot be used as non-type template parameters 
double process ( double v) // but can be used as template parameters 
{
     return v * VAT; 
} 
 
template <std :: string name> // ERROR: class Type cannot be used as a non-type template parameter 
class MyClass { // allowed as template parameters 

};

When passing template arguments to pointers or references, the objects must not be string literals, temporaries, or data members and other subobjects. Because these restrictions were relaxed with each and every C++ version before C++17, additional constraints apply:

When passing pointers or references to template arguments, objects cannot be string literals, temporary objects or data members, and other sub-objects. Because every C ++ version before C ++ 17 relaxes these restrictions, additional restrictions apply to:

• In C++11, the objects also had to have external linkage.

  In C ++ 11, objects must also have external links.

• In C++14, the objects also had to have external or internal linkage.

  In C ++ 14, objects must also be externally or internally linked.

Thus, the following is not possible:

Therefore, the following is not possible:

template < char  const * name>
 class MyClass { 
}; 

MyClass < " hello " > x; // ERROR: String literals are not allowed ("hello")

However there are workarounds (again depending on the C++ version):

However, there are some workarounds (again dependent on the C ++ version):

extern  char  const s03 [] = " hi " ; // external link 
char  const s11 [] = " hi " ; // internal link 

int main () 
{ 
    Message <s03> m03; // OK (all versions) 
    Message <s11 > m11; // OK, starting from C ++ 11 
    static  char  const s17 [] = " hi " ; // No link (static local variable is no link?) 
    Message <s17> m17; // OK, from C + +17 start 
}

In all three cases a constant character array is initialized by "hello" and this object is used as a template parameter declared with char const*. This is valid in all C++ versions if the object has external linkage (s03), in C++11 and C++14 also if it has internal linkage (s11), and since C++17 if it has no linkage at all.

In all three cases, constant character array objects are initialized by "hello". This object is used in the template parameter declared as char const *. If the object is an external link (s03), then all versions in C ++ are valid. In C ++ 11 and C ++ 14, if the object is an internal link, it will also work. Starting from C ++ 17, if the object is not linked at all, it will also work.

 

See Section 12.3.3 on page 194 for a detailed discussion and Section 17.2 on page 354 for a discussion of possible future changes in this area.

For a detailed discussion, see section 12.3.3 on page 194. For a discussion of possible changes to this place in the future, please see section 17.2 on page 354.

 

Avoiding Invalid Expressions

Avoid invalid expressions

 

Arguments for nontype template parameters might be any compile-time expressions.

For example:

Non-type template parameters can be any expression at compile time.

template<int I, bool B>
class C;
…
C<sizeof(int) + 4, sizeof(int)==4> c;

However, note that if operator> is used in the expression, you have to put the whole expression into parentheses so that the nested > ends the argument list:

However, please note that if you have used the ">" operator in the expression, you must put the entire expression in parentheses to nest the> end argument list:

C < 42 , sizeof ( int )> 4 > c; // ERROR: The first ">" ends the template argument list 

C < 42 , ( sizeof ( int )> 4 )> c; // OK

 

Guess you like

Origin www.cnblogs.com/5iedu/p/12716483.html