#include <iostream>
using namespace std;
template<typename T> class slist
{
struct Node
{
T data;
Node* next;
Node( T d, Node* n ) : data(d), next(n) {}
};
Node* head;
public:
slist() : head(0) {}
void push_front( T a ) { head = new Node( a, head ); }
// list의각요소를접근하기위해스마트포인터를넣는다.
// 내포로만들거나외부에(그리고내부에typedef로선언) 만들수있다.
class iterator
{
Node* current;
public:
typedef T value_type;
iterator( Node* init = 0 ) : current( init ) {}
iterator& operator++()
{
current = current->next;
return *this;
}
T& operator* ()
{
return current->data;
}
bool operator !=( const iterator& i )
{
return (current != i.current);
}
};
//-------------------------------------------------------
// 이제slist의처음과past the end iterator를리턴하는함수를제공한다.
iterator begin() { return iterator(head); }
iterator end() { return iterator( 0 ); }
};
/*
// 주어진구간의합을출력하는알고리즘을만들고싶다.
// 컴파일러에의한타입추론(type ??), 타입을알지못하므로컴파일러에게맡긴다??
// 단점: 리턴값을갖지못한다. 타입을모르므로?? void!!
template<typename T, typename T2> void sum_imp( T first, T last, T2 init )
{
T2 s = init;
while ( ++first != last )
{
s = s + *first;
}
cout << s << endl;
}
template<typename T> void sum( T first, T last )
{
sum_imp( first, last, *first );
}
*/
// 버전2. 주어진구간의합을리턴하는함수를만들어보자.
// 모든반복자는자신과연관된type을typedef로가지고있다.( value_type으로꺼내면된다. )
// 간접층을만들어type문제를해결한다. (int, int), 반복자특성클래스.
template<typename T> struct xiterator_traits
{
typedef typename T::value_type value_type;
};
// template 부분전문화( 포인터로되어있는것)
template<typename T> struct xiterator_traits<T*>
{
typedef T value_type;
};
template<typename T>
typename xiterator_traits<T>::value_type sum( T first, T last )
{
//typename T::value_type s = *first;
// 어떠한타입이올지모르므로0을대입해서는안된다.
typename xiterator_traits<T>::value_type s = *first;
while ( ++first != last )
{
s = s + *first;
}
return s;
}
void main()
{
int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int n2 = sum( x, x+10 );
slist<int> s;
s.push_front( 10 );
s.push_front( 20 );
s.push_front( 30 );
s.push_front( 40 );
//slist안에있는모든요소의합을구하고싶다.
int k = sum( s.begin(), s.end() );
cout << k << endl;
}
////////////////////////////////////////////////////////////////////
// iterator_category 의 구현
{
typedef typename T::value_type value_type;
typedef typename T::iterator_category iterator_category;
};
// template 부분전문화( 포인터로되어있는것)
template<typename T> struct xiterator_traits<T*>
{
typedef T value_type;
typedef random_access_iterator_tag iterator_category;
};
//임의접근일경우
template<typename T> void xadvance(T& p, int n ,random_access_iterator_tag)
{
p += n;
}
template<typename T>
void xadvance( T& p, int n )
{
xadvance( p, n, xiterator_traits<T>::iterator_category() );
}
void main()
{
int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int *p = x;
xadvance( p, 3 ); // p의반복자를3만큼전진해야한다. p+n 처리를하자.
cout << *p << endl; // 4이나와야한다.
}