开发者

compile time error regarding template function instantiation

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){
   ...
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜