博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

模版完整: 模板形参与模板实参

Posted on 2018-04-27 10:57  bw_0927  阅读(609)  评论(0)    收藏  举报

http://en.cppreference.com/w/cpp/language/template_parameters

http://zh.cppreference.com/w/cpp/language/templates

 

 

模板形参与模板实参

模版形参类型:

  • 非类型模板形参;
  • 类型模板形参;
  • 模板模板形参。

Non-type template parameter  非类型模版形参

 
type name(optional) (1)  
 
type name(optional) default (2)  
 
type ... name(optional) (3) (since C++11)
 
auto name (4) (since C++17)
 
1) A non-type template parameter with an optional name.
2) A non-type template parameter with an optional name and a default value.
3) A non-type template parameter pack with an optional name.    (非类型参数包)
4) A non-type template parameter with a deduced type (note, it may also be auto ** or any other type that includes the placeholder auto)

 

type is one of the following types (optionally cv-qualified, the qualifiers are ignored):    type的可用类型

 

 

Type template parameter  类型模版形参

 
typename name(optional) (1)  
 
class name(optional) (2)  
 
typename|class name(optional) default (3)  
 
typename|class ... name(optional) (4) (since C++11)
 
1) A type template parameter with an optional name.
2) Exactly the same as 1).
3) A type template parameter with an optional name and a default.
4) A type template parameter pack with an optional name.       (类型参数包)

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.

There is no difference between the keywords class and typename in a type template parameter declaration.

 

 

Template template parameter     模版模版形参


template<auto n> struct B { /* ... */ };
B<5> b1;   // OK: non-type template parameter type is int
B<'a'> b2; // OK: non-type template parameter type is char
B<2.5> b3; // error: non-type template parameter type cannot be double
template<auto...> struct C {};
C<'C', 0, 2L, nullptr> x; // OK

https://blog.csdn.net/zhangxiao93/article/details/50747862

非类型模板参数(nontype template parameters), 可以使用整型类型(integral type),指针(pointer) 或者是 引用(reference);

绑定非类型整数形参(nontype integral parameter) 的 实参(argument) 必须是常量表达式(constant expression, constexpr);

不能把普通的局部对象或者动态对象 绑定 指针或引用的非类型形参, 可以使用全局类型进行绑定;

关于类模板(class template)中非类型模板参数的写法,参见: http://en.cppreference.com/w/cpp/language/class_template

下面例子包含了模板类型是 整型, 指针, 引用, 函数指针 的函数的常见写法;

注意指针和引用的实参是全局变量;

 

#include <iostream>  
#include <vector>  
#include <cstring>  
  
using namespace std;  
  
//整型模板  
template<unsigned N, unsigned M>  
bool compare (const char (&p1)[N], const char (&p2)[M])  
{  
    std::cout << "size : " << N << " " << M << std::endl;  
    return strcmp(p1, p2);  
}  
  
//指针  
template<const char* C>  
void pointerT(const char* str){  
    std::cout << C << " " << str << std::endl;  
}  
  
//引用  
template<char (&ra)[9]>  
void referenceT(const char* str){  
    std::cout << ra << " " << str << std::endl;  
}  
  
char ca[] = "Caroline"; //初始化指针  
char cr[9] = "Caroline"; //初始化引用, 包含一个结尾符号  
  
void f(const char* c) {std::cout << c << std::endl; }  
  
//函数指针  
template<void (*F)(const char*)>  
void fpointerT(const char* c) {  
    F(c);  
}  
  
int main(void)  
{  
    if(compare("Caroline", "Wendy")) {  
        std::cout << "Caroline is long." << std::endl;  
    } else {  
        std::cout << "Wendy is long." << std::endl;  
    }  
  
    //无法使用局部变量或者动态变量作为模板参数  
    pointerT<ca>("Wendy"); //指针  
  
    referenceT<cr>("Wendy"); //引用  
  
    fpointerT<f>("Caroline Wendy"); //函数指针  
  
    return 0;  
}  

  输出:

  1. size : 9 6  
  2. Caroline is long.  
  3. Caroline Wendy  
  4. Caroline Wendy  
  5. Caroline Wendy