zoukankan      html  css  js  c++  java
  • 模板编程中的技巧

    关键字 typename

    在C++标准化过程中,引入关键字typename是为了说明;模板内部的标识符可以是一个类型。譬如下面的例子:

    template<typename T>
    class MyClass{
        typename T::SubType *ptr;
        ...
    };
    

      上面的程序中,第2个typename被用来说明:SubType是定义与类T内部的一种类型。因此,ptr是一个指向T::SubType类型的指针。

      如果不使用typename,SubType就会被认为是一个静态成员,那么它应该是一个具体的变量或对象,于是,下面表达式:

    T::SubType *ptr;

      会被看作是类T的静态成员SubType和ptr的乘积。

    .template构造

    我们在引入typename之后,发现了一个很相似的问题。考虑下面这个使用标准bitset类型的例子:

    template<int N>
    void printBitset(std::bitset<N> const& bs)
    {
        std::cout<<bs.template to_string<char,char_traits<char>,allocator<char> >();
    }
    

      本例中有一个奇怪的构造:.template。如果没有使用这个template,编译器将不知道下列事实:bs.template后面的小于号(<)并不是数学中的小于号,而是模板实参列表的起始符号;那么只有在编辑器判断小于号(<)之前,存在依赖于模板参数的构造,才会出现这种问题。在这个例子中,传入参数bs就是依赖于模板参数N的构造。

    使用this->

      对于基类的类模板,自身使用名称x并不一定等同于this->x。即使该x从基类继承获得的,也是如此。例如:

    template <typename T>
    class Base{
        public:
            void exit();
    };
    
    template<typename T>
    class Derived:Base<T>{
        public:
            void foo() {
                exit();  //调用外部的exit()或者出现错误
            }
    };
    

      在这个例子中,在foo()内部决定要调用哪一个exit()时,并不会考虑基类Base中定义的exit()。因此,你如果不是获得一个错误,就是调用了另一个exit()。

      注意:对于那些在基类中声明,并且依赖于模板参数的符号(函数或者变量等),你应该在它们前面使用this->或者Base<T>::。如果希望完全避免不确定性,你可以(使用诸如this->和Base<T>::等)限定(模板中)所有的成员访问。

  • 相关阅读:
    王立平--scard0与scard1分别指的是什么?以及路径获取
    算法导论 第7章 高速排序
    [转]php-fpm配置具体解释
    ViewPager实现页卡的最新方法--简洁的TabLayout(谷歌支持包)
    MFC对话框贴图基础上控件Stasic变成透明的
    学习Opencv 2.4.9(二) ---操作像素
    Dynamics CRM 2015/2016 Web API:Unbound Action 和 Bound Action
    网页元素居中攻略记_(6)图片水平垂直居中
    【计算机视觉】粒子滤波跟踪
    【python】异常处理
  • 原文地址:https://www.cnblogs.com/wuchanming/p/4060210.html
Copyright © 2011-2022 走看看