码迷,mamicode.com
首页 > 编程语言 > 详细

[c++] Templates

时间:2016-12-27 22:20:28      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:成员访问   closed   function   int   diff   false   否则   关键字   overload   

Template是编译时多态。所有的模板都是在编译时产生对应的代码,它没有面向对象中的虚表,无法实现动态多态。

 

Function Template

A function template is a prescription for the compiler to generate particular instances of a function varying by type.

”变量类型“的部分放在一块,与“变量类型无关”的部分放在另一边。

放在"头文件“中,声明和实现建议这么做。其他方式不推荐。

 

Name Resolution

  • designer & client
  • Only three kinds of implicit conversions for type parameters:

技术分享

 

参数的类型不同的数字比较的话,例如:int , double

使用例如:min(static_cast<double> i, d)的方式。

 

decltype (不用类型转换,编译器自己推导)

编译时类型推导,除了我们说过的auto关键字,还有本文的decltype。

(1) 解决模板函数返回值不确定情况:

template <typename T, typename U>
auto mymin(T a, U b) -> decltype(a < b ? a : b) {
    return a < b ? a: b;
}

泛型编程中结合auto,用于追踪函数的返回值类型!

 

(2) 根据变量推导齐类型:

int i;
const &j = i;
int *p = i;
int k;

decltype(i) x; // int x: i is a variable
decltype(j) y = k; // int &y = k: j is an lvalue
decltype(*p) z = k; // int &z = k: *p is an lvalue
decltype((i)) w = k; // int &w = k: (i) is an lvalue

Ref: C++11特性:decltype关键字

 

(3) 与using/typedef合用,用于定义类型:

using size_t = decltype(sizeof(0));//sizeof(a)的返回值为size_t类型
using ptrdiff_t = decltype((int*)0 - (int*)0);
using nullptr_t = decltype(nullptr);
vector<int >vec;
typedef decltype(vec.begin()) vectype;
for (vectype i = vec.begin; i != vec.end(); i++)
{
    //...
}
 

(4) 重用匿名类型:

在C++中,我们有时候会遇上一些匿名类型,而借助decltype,我们可以重新使用这个匿名的结构体:

struct 
{
    int d ;
    doubel b;
}anon_s;
decltype(anon_s) as ; //定义了一个上面匿名的结构体

 

decltype推导四规则

  1. 如果e是一个没有带括号的标记符表达式或者类成员访问表达式,那么的decltype(e)就是e所命名的实体的类型。此外,如果e是一个被重载的函数,则会导致编译错误。
  2. 否则 ,假设e的类型是T,如果e是一个将亡值,那么decltype(e)为T&&
  3. 否则,假设e的类型是T,如果e是一个左值,那么decltype(e)为T&。
  4. 否则,假设e的类型是T,则decltype(e)为T。

注意小括号的作用:
int func(void)
{
    int i = 10; 
    decltype(i) a = i;
    decltype((i)) b = i;

    a = 10; 
    cout << "i = " << i << endl;
    b = 20;   // b变为 引用
    cout << "i = " << i << endl;

    return 0;
}

 

技术分享
int decipline(void)
{

    int i = 4;
    int arr[5] = { 0 };
    int *ptr = arr;
    struct S{ double d; }s ;

//    void Overloaded(int);
//    void Overloaded(char);//重载的函数

    int && RvalRef();
    const bool Func(int);

    //规则一:推导为其类型
    decltype (arr) var1; //int 标记符表达式

    decltype (ptr) var2;//int *  标记符表达式

    decltype(s.d) var3;//doubel 成员访问表达式

    //decltype(Overloaded) var4;//重载函数。编译错误。

    //规则二:将亡值。推导为类型的右值引用。

    decltype (RvalRef()) var5 = 1;

    //规则三:左值,推导为类型的引用。

    decltype ((i))var6 = i;     //int&

    decltype (true ? i : i) var7 = i; //int&  条件表达式返回左值。

    {
        int x = 10;
        float y = 1.11;

        decltype(true?x:y) c = (false?x:y);

        cout << "c = " << c << endl;
    }

    decltype (++i) var8 = i; //int&  ++i返回i的左值。

    decltype(arr[5]) var9 = i;//int&. []操作返回左值

    decltype(*ptr)var10 = i;//int& *操作返回左值

    decltype("hello")var11 = "hello"; //const char(&)[9]  字符串字面常量为左值,且为const左值。


    //规则四:以上都不是,则推导为本类型

    decltype(1) var12;//const int

    decltype(Func(1)) var13=true;//const bool

    decltype(i++) var14 = i;//int i++返回右值


    return 0;
}
四个规则的示例


左值推导为类型的引用:
如何判断是否是左值呢?
cout << is_lvalue_reference<decltype(++i)>::value << endl;

 

 


模板的健壮性

 若要比较字符串,使用函数override.

const char *s = "xyz";
const char *t = "abc";

/* 返回了数字,认为是地址,也就是数组的首地址 */ cout
<< min(s, t) << endl;

 

模板的设计 更加健壮。如下:

技术分享

 

 

 template function的默认参数 也可以设置,实现健壮性

技术分享

 

 

template‘s variadic function ,进一步健壮

 技术分享

注意关键写法:

template <typename A, typename... B>
void print(A head, B... tail) {
  ...  
}

 

continue...

[c++] Templates

标签:成员访问   closed   function   int   diff   false   否则   关键字   overload   

原文地址:http://www.cnblogs.com/jesse123/p/6227403.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!