乐趣区

关于c++:c中typenametypedef以及using关键字用法

在 c ++ 的规范库中,因为类继承关系比较复杂和模板应用比拟多的起因,源代码中充斥着 typename、typedef 和 using 这三个关键字,所以在持续分析规范库源码之前,明天就来介绍一下这三个关键字的作用。

一、typename 关键字

typename 的第一个作用是用作模板外面,来申明某种类型,比方这样的:

template<typename _Tp, typename _Alloc>
    struct _Vector_base;

最开始的时候申明模板形参,也会应用 class,但咱们都晓得 class 总要是用来指定一个类名,据说是为了防止混同,所以起初减少了 typename 这个关键字,它通知编译器,跟在它前面的字符串是一个不确定的类型,而不是变量或者其余什么货色。

typename 在 stl 中还有另外一种作用,假如有这样一段代码:

//test.cpp
#include <ext/alloc_traits.h>
using namespace std;

template<typename _Tp, typename _Alloc>
class AA
{typedef  typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type;};

这里顺便说一下 rebind 后面为啥要放一个 template,它是为了通知编译器前面的 <> 是用于指定模板参数,而进行比拟。

这个时候咱们应用 g++ -c test.cpp -o test.o 是能够编译通过的,但如果咱们去掉第三个 typename 看,会产生什么呢?

再次编译,报错如下:

test.cpp:8:10: 谬误:‘typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Tp>::other’之前须要‘typename’,因为‘typename __gnu_cxx::__alloc_traits<_Alloc>::rebind<_Tp>’是一个有依赖的作用域
 typedef  __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type;

编译器间接指明了须要一个 typename,实际上 typename 在这里也是指定它前面的字符串为类型,这是因为对于形如 AA::BB 这样的模式,它有可能是一个类型,也有可能是类的动态成员,这个时候加上 typename 就是为了通知编译器,它前面的一大串字符串都是一个类型。

二、typedef 关键字

还是这段代码,咱们增加一行:

#include <ext/alloc_traits.h>
using namespace std;

template<typename _Tp, typename _Alloc>
class AA
{
    typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other _Tp_alloc_type;
    _Tp_alloc_type tp;
};

这个 typedef 实际上就是给类型取了一个别名,将 __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other 这么一长串的类型取了一个简略的别名,要是不取别名,这样长的类型真的是不忍直视。

当然啦,typedef 除了这种模式以外,其实很多时候也会给函数指针取别名哦,如下:

typedef int (*func)(int a, int b);

这个时候实际上就是给 int * (int a, int b) 这个函数指针取了一个别名 func。

三、using 关键字

对于 using 关键字,最开始晓得是因为这行代码:

using namespace std;

所以它的第一个作用就是申明命名空间,应用形如 using namespace 命名空间名; 这样的模式通知编译器,后续应用该命名空间外面的变量或者类型都无需再加上 std 的前缀,这个是对于命名空间整体的申明。

还有一种模式是:

using std::cout;
using std::endl;

这种就是只独自申明命名空间外面的某个名字,命名空间外面其余的货色是无奈间接应用的,此时咱们只能应用 cout 和 endl 这两个。

using 的第三种应用模式是:

class parent
{
protected:
    int m;
};

class child: public parent
{
public:
    using parent::m;
};

int main()
{
    child c;
    c.m = 2;
    return 0;
}

m 在 parent 外面是 protected 类型,然而在 child 外面应用 using 申明当前,它能够被间接拜访,其实这个时候它的作用相似于引入命名空间中的变量,此处是引入父类中的爱护类型成员变量,对于这种用法,咱们不开展多说,只有晓得有这样的作用,当前看到了这样的代码晓得它是怎么个意思就行了。

using 在 c ++11 当前又有了一种新的作用,那就是与 typedef 一样,给类型指定别名,模式是这样的:

using 别名 = 类型;

咱们把下面 typedef 那里的代码改一下,如下:

#include <ext/alloc_traits.h>
using namespace std;

template<typename _Tp, typename _Alloc>
class AA
{
    using  _Tp_alloc_type = typename __gnu_cxx::__alloc_traits<_Alloc>::template rebind<_Tp>::other;
    _Tp_alloc_type tp;
};

对于函数指针,还能够这样:

using func = int (*)(int a, int b);

这样看来,using 感觉上比 typedef 更加直观一下哈。

好了,对于三个关键字的简略介绍就到这里了,下篇文章再会呀。

退出移动版