• C++


    声明template参数时, 前缀关键字class和typename可以互换;

    使用关键字typename标识嵌套从属类型名称, 但不需在基类列表和成员初始化列表内使用.

     

    从属名称(dependent names): 模板(template)内出现的名称, 相依于某个模板(template)参数, 如T t;

    嵌套从属名称(nested dependent names):从属名称在class内呈嵌套装, 如T::const_iterator ci;

    非从属名称(non-dependent names): 不依赖任何template参数的名称, 如int value;

     

    如果不特定指出typename, 嵌套从属名称, 有可能产生解析(parse)歧义.

    任何时候在模板(template)中指涉一个嵌套从属类型名称, 需要在前一个位置, 添加关键字typename;

    否则报错(GCC): error: need 'typename' before 'T::xxx' because 'T' is a dependent scope

     

    代码:

    /*
     * BInsertSort.cpp
     *
     *  Created on: 2014.4.17.
     *      Author: Spike
     */
    
    #include <iostream>
    #include <string>
    #include <vector>
    
    using namespace std;
    
    template<typename T>
    void print2nd(const T& container) {
        typename T::const_iterator iter(container.begin()); //未加typename, 报错
        ++iter;
        int value = *iter;
        std::cout << value;
    }
    
    int main () {
        vector<int> vi = {1,2,3,4,5};
        print2nd(vi);
    
        return 0;
    }

    输出:

    2
    

    例外:嵌套从属类型名称, 如果是基类列表(base class list)成员初值列(member initialization list)中,不使用typename;

    代码:

    /*
     * BInsertSort.cpp
     *
     *  Created on: 2014.4.17
     *      Author: Spike
     */
    
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    struct Number {
    	Number(int x) {
    		std::cout << "Number = " << x << std::endl;
    	}
    };
    
    template<typename T>
    struct Base{
    	typedef Number Nested;
    };
    
    template<typename T>
    class Derived: public Base<T>::Nested { //不用typename
    public:
    	explicit Derived(int x) : Base<T>::Nested(x) { //不用typename
    		typename Base<T>::Nested temp(7); //必须使用
    	}
    };
    
    int main () {
    	Derived<int> d(5);
    
    	return 0;
    }
    
    输出:
    Number = 5 Number = 7

    当使用特性类(traits class)时, 必须使用typename, 如

    代码:

    /*
     * BInsertSort.cpp
     *
     *  Created on: 2014.4.17
     *      Author: Spike
     */
    
    #include <array>
    #include <iostream>
    
    using namespace std;
    
    template<typename T>
    void workWithIter(T iter) {
    	typedef typename std::iterator_traits<T>::value_type value_type; //使用typename
    	value_type temp(*iter);
    	std::cout << "temp = " << temp << std::endl;
    
    }
    
    int main () {
    	std::array<int, 5> ai = {1,2,3,4,5};
    	std::array<int, 5>::iterator aiIter = ai.begin();
    	workWithIter(aiIter);
    	return 0;
    }
    

      输出:

    temp = 1
    

      

  • 相关阅读:
    JavaWeb图片显示与存储
    sql将日期按照年月分组并统计数量
    response的作用
    TCP/IP学习笔记(1)-----基本概念
    TCP/IP学习笔记(2)---数据链路层
    TCP/IP学习笔记(3)----IP,ARP,RARP协议
    TCP/IP学习笔记(4)------ICMP,ping,traceroute
    TCP/IP学习笔记(5)------IP选路
    如何运行简单的scrapy
    difference among String,StringBuilder,StringBuffer
  • 原文地址:https://www.cnblogs.com/wuchanming/p/3766174.html
Copyright © 2020-2023  润新知