代码改变世界

C++ typename 用法

2012-06-13 09:33  youxin  阅读(1834)  评论(0编辑  收藏  举报

 看一下自定义类型如何在函数头返回类定义的类型:

  一个vec初略模板:

template <class T> class Vec {
public:
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef size_t size_type;
    typedef T value_type;
    typedef T& reference;
    typedef const T& const_reference;
    
    iterator erase(iterator it);
    .......
    ...
    
private:
    ....
};

 

  要实现erase函数,返回值为iterator,下面的函数定义可以吗?

template<class T>
Vec<T>::iterator Vec<T>::erase(iterator it)
{

   .........
   
   
 }
    

 上面的是错误的,应该在

Vec<T>::iterator 
前加typename关键字。如下:
template<class T>
typename Vec<T>::iterator Vec<T>::erase(iterator it)
{

   .........
   
   
 }
    

 

 为什么要加typename,因为iterator这个类型是在Vec<T>类定义的。C++规定:无论何时,如果使用了一个依赖与模板参数的类型时(如vector<T>),而且你想要使用这个类型的成员函数(如size_type)本身就是一个类型就必须在整个名字前加上typename

现在要你写一个求vector中值的模板函数,想想怎么写。
template<class T>
T median(vector<T> v) { typedef typename vector<T>::size_type vec_sz; vec_sz size=v.size(); if(size==0) throw.domain_error("median of an empty vector"); sort(v.begin(),v.end()); vec_sz mid=size/2; return size%2==0?(v[mid]+v[mid-1]):v[mid]); }

 上面的typename告诉系统:vector<T>::size_type 是一个类型的名字,虽然系统并不知道类型T是什么,无论什么时候,如何你使用一个依赖于模板参数的类型时,比如vector<T>,而且 你想要使用这个类型的成员时,比如size_type,它本身也是一个类型时,你必须在整个名字之前加上typename,以便让系统知道要把这个名字当成类型来对待

msdn解释:

The typename keyword tells the compiler that an unknown identifier is a type.

typename identifier;

Use this keyword only in template definitions. For example:

// typename.cpp
template<class T> class X
{
   typename T::Y m_y;   // treat Y as a type
};

int main()
{
}

This keyword can also be used in place of class in template parameter lists. For example, the following statements are identical:

template<class T1, class T2>...
template<typename T1, typename T2>...


深入:
http://pages.cs.wisc.edu/~driscoll/typename.html

  http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fkeyword_typename.htm