I am trying to write a container class with iterator. This is my class:
template <class T>
class C{
private:
T* v;
int MAX_SIZE;
int i;
public:
C (int size){
MAX_SIZE = size;
v = new T (MAX_SIZE);
i = 0;
}
~C(){ delete v; }
class iterator{
private:
T* v;
public:
iterator(T* ip){ v = ip; }
void operator++ (){ ++v; }
void operator-- (){ --v; }
T operator* () { return *v; }
bool operator!= (const iterator & it) { return v != it.v; }
};
iterator begin(){ return iterator (v); }
iterator end() { return iterator (&v[MAX_SIZE]); }
void push_back (T e){
if (i == MAX_SIZE) throw MaxSizeReached();
v[i] = e;
++i;
}
class MaxSizeReached{};
};
template <class T>
void print(typename C<T>::iterator & start, typename C<T>::iterator & end){
for (typename C<T>::iterator s (start), e (end); s != e; ++s){
std::cout << *s << '\n';
}
}
int main(){
C<int> ic (3);
C<float> fc (4);
C<char> cc (3);
ic.push_back (56);
ic.push_back (76);
ic.push_back (88);
print<int>(ic.begin(), ic.end());
return 0;
}
g++ 4.5 throws this error:
templatizedCustomIterator.c++: In function ‘int main()’:
templatizedCustomIterator.c++:71:35: error: no matching function for call to ‘print(C<int>::iterator, C<int>::iterator)
Which is incorrect - definition of print() or the call?开发者_如何学C
Have a look the function template:
template<T>
void print(typename C<T>::iterator & start, typename C<T>::iterator & end);
And your usage:
print(ic.begin(), ic.end());
So the problem is, T
cannot be deduced from the function argument. The Standard calls it non-deducible context. Here I've explained similar question in detail, read this:
- C++, template argument can not be deduced
Now the question is, how would you implement the function template? So here is one good solution:
template <class FwdIterator>
void print(FwdIterator start, FwdIterator end)
{
for ( ; start != end; ++start)
{
std::cout << *start << '\n';
}
}
If you pass a third argument as:
template <class FwdIterator>
void print(FwdIterator start, FwdIterator end, std::ostream &out)
{
for ( ; start != end; ++start)
{
out << *start << '\n';
}
}
then you can use this to print to file as well:
print(ic.begin(), ic.end(), std::cout); //print to console
std::ofstream file("file.txt")
print(ic.begin(), ic.end(), file); //print to file
The print
function has to take the parameters as const
references, else it can't be used with temporary values like those returned by begin()
and end()
:
template <class T>
void print(const typename C<T>::iterator & start, const typename C<T>::iterator & end){
...
}
精彩评论