如何获得变量和返回参数的类型(上篇)

在我们平时的代码编写中,当我们把变量显式的写出来的时候我们能够知道它是哪种类型的,例如:int a;我们能看出来这里的a是整型变量,但是如果我们想获取a的类型给怎么做呢?或这说在其它函数给我传过来参数我如何确认参数的类型以及如何用这个参数的类型去定义另外一个变量呢?
下面我们来看看如何获取一个参数的类型:

#include<iostream>
using namespace std;
template<class T>
void fun(T a)//查看T类型
{
    char *ch = typeid(a).name();//也可直接输出,这里是为了提醒大家typeid()函数最后是以字符串输出,所以不能直接用来定义变量
    cout<<ch<<endl;
}
int main()
{
    int a;
    fun(a);
}

在上面的代码中只是简单的展现了RTTI(运行时类型识别)性质中的typeid()函数的使用以及我们在像fun这样的模板函数中如何的知T的类型,就可以使用typeid输出查看,但是这不是我们要说的重点,重点是我们在的知了类型的同时还能够使用这个类型在相应时刻定义另外一个变量,简单的说就是我们不仅要知道类型而且还可以用这个类型自如定义变量。下面我们来看看这个机制:

#include<iostream>
using namespace std;
template<class I, class T>
void fun_impl(I iter, T t)//这里的I是int *,T是int
{
    T tmp;//这里可以用T来定以一个变量
    //...在这里做fun()的工作
}
template<class T>
inline//内联,可以提高效率
void fun(T i)//这里的T可以推测出来是int *
{
    fun_impl(i, *i);//这里把fun函数的所有工作转移走
}
int main()
{
    int a;
    fun(&a);
    return 0;
}

上面两段代码都是function template的参数推导机制,但是这种机制也有解决不了的问题,对于返回值类型的推导使用function template是无法完成的,所以上面的方法被称为参数推导。
下面我们来看看返回值推导过程:

#include<iostream>
using namespace std;

template<class T>
struct MyIter
{
    typedef T value_type;//内嵌型别声明
    T *ptr;
    MyIter(T *p=0):ptr(p)
    {}
    T & operator*()const//重载*
    {
        return * ptr;
    }
};

template<class I>
typename I :: value_type func(I iter)//typename在这里是告诉系统value_type是个类型,I就是MyIter接头体类名
{
    return *ite;
}

int main()
{
    MyIter<int> ite(new int(8));
    cout<<func(ite);
    return 0;
}

在这段代码中有两点需要注意:1、是在定义func()函数的时候,由于我们要确定的是返回值的类型,在vc6.0下面我们可以不加typename这个关键字,但是在其他编译器下必须加,意思就是告诉系统value_type是个类型,2、这里需要operator *,为了就是在func函数中返回值的时候返回数据。这段代码虽然是解决了function template无法推导函数返回值类型的问题,但是它也有局限性,就是无法跳出结构体和类。为了解决这一难题,设计者们有巧妙的设计了另外一个方法——偏特化,在这里我们先简单的介绍一下偏特化,特化就是我们把集合中的一种情况单独列出来特殊化处理,换句话说就是泛化设计中提供一个特化版本(也就是将泛化版本中的某些template参数赋予明确的指定)。代码中最能体现,如下:

#include<iostream>

using namespace std;

template<class T1, class T2>
class Test
{
public:
    Test()
    {
        cout<<"111"<<endl;
    }

};

template<class T>
class Test<typename T, int>
{
public:
    Test()
    {
        cout<<"222"<<endl;
    }

};

int main()
{
    Test<char, float> t;
    Test<char, int> t1;
}

这里的代码知识简单的描述了一种模板类特化类型,在《C++ Templates中文版》中第十四章第四节详细的列举了多种类模板特化类型,大家可以下载阅读。这里的代码中只是把模板参数int指定,只要定义对象模板第二个参数为int就一定由第二个类为该对象所用。
本篇未完我们下篇继续讲解我们STL里的中级绝招,如何写一个通用的函数获取返回值类型。之类我们稍微的提一下通过萃取和偏特化处理来完成的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值