typename关键字的使用

忘了……模板啊忘光了 T T

今天有同学考C++,后来问了我一个问题:要写一个Set类,支持拷贝构造函数、+=、-=、=、<<等运算符的重载。我偷懒用std::list<T>给实现了一个版本,因为那题目貌似原本有要求用链表来实现(但却没说那链表一定要自己实现,OTL),而且直接用STL的set<T>也未免太“没诚意”了,呵呵
但遇到了点小问题:
我想直接把std::list<T>::iterator用作Set<T>的iterator,但是怎么编译都不行,说std::list<T>不是Set<T>的派生类什么的。然后我就严重被郁闷了……

问了axx大才知道原来在std::list<T>::iterator前加上typename关键字就行了。因为std::list<T>在实例化之前,编译器没办法判断iterator到底是成员还是类型,所以会出错。

于是代码就像这样(别笑,大家都是为了偷懒……本来给集合定义一个顺序迭代器也是够怪的,不过不想自己实现内部用的链表啊):
set.h
#ifndef SET_H_INCLUDED
#define SET_H_INCLUDED

#include <list>
#include <iostream>
#include <algorithm>

template<typename T>
class Set {
std::list<T> m_data;

public:
typedef typename std::list<T>::iterator iterator;
typedef typename std::list<T>::const_iterator const_iterator;

Set( ) { }

Set( T array[], T count ) {
for (T i = 0; i < count; ++i) {
m_data.push_back( array[ i ] );
}
m_data.unique( );
}

Set( const Set<T>& rhs ) {
if ( &rhs == this ) return;
m_data.clear( );
m_data = rhs.m_data;
}

Set<T>& operator =( const Set<T>& rhs ) {
if ( &rhs == this ) return *this;
m_data.clear( );
m_data = rhs.m_data;
return *this;
}

Set<T>& operator +=( const T& value ) {
if ( std::find( m_data.begin( ), m_data.end( ), value ) == m_data.end( ) ) {
m_data.push_back( value );
}
return *this;
}

Set<T>& operator -=( const T& value ) {
m_data.remove( value );
return *this;
}

iterator begin( ) {
return m_data.begin( );
}

iterator end( ) {
return m_data.end( );
}

const_iterator begin( ) const {
return ((const std::list<T>&)m_data).begin( );
}

const_iterator end( ) const {
return ((const std::list<T>&)m_data).end( );
}

friend std::ostream& operator <<( std::ostream& out, const Set<T>& set ) {
out << "[";
typename Set<T>::const_iterator it = set.begin( );
if ( it != set.end( ) ) {
out << *it++;
if ( it != set.end( ) ) {
for ( ; it != set.end( ); ++it ) {
out << ", " << *it;
}
}
}
out << "]";
return out;
}
};

#endif // SET_H_INCLUDED

注意13、14、68行里typename的使用。

main.cpp
#include <iostream>
#include "set.h"

using namespace std;

int main()
{
int a[] = { 1, 3, 5, 7, 9 };
int x = 2, y = 3;
Set<int> s1( a, 5 );
Set<int> s2;

s1 += x;
s2 = s1;
s2 -= y;

cout << s1 << endl << s2 << endl;

return 0;
}


axx大提到还有一个using declaration可以用于从基类把名字引入到派生类的作用域中,嗯这个我也印象模糊了……
C++真是……我还是写得太少了。平时还是应该多写点的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值