2

Possible Duplicate:
no matching function error using template template parameters in a function

Good mornig I don't understand because I obtain compile error by implementing as global function the operator== (in class myList::iterator) If I realize the operator== as member function the code compile.

The error is

error: no match for operator== in it == it1
note: candidate is:
note: tempalte<class T> bool operator==(const typename myList<T>::iterator&,const typename myList<T>::iterator&)

The code is:

#include <iostream>
#include <cstdlib>
#include <iterator>
#include <typeinfo>

template <class T>
class myList;

template <class T>
bool operator==(const typename myList<T>::iterator& lhs,const typename myList<T>::iterator& rhs);
template <class T>
bool operator!=(const typename myList<T>::iterator& lhs,const typename myList<T>::iterator& rhs);

template <class T>
class myList
{
private:
  class myInfo;
public:
  //CTR DEFAULT
  myList():_pInfo(NULL)
  {}
  myList(T value):_pInfo(new myInfo(value))
  {}
  //  class iterator;
  //  friend class iterator;
  class iterator{
  public:
    //creo gli iteratori
    iterator():_pMyInfoIt(NULL)
    {}
    iterator(myInfo* p):_pMyInfoIt(p)
    {}
    iterator(const iterator& it):_pMyInfoIt(it._pMyInfoIt)
    {}
    iterator& operator=(const iterator& it)
    {
      _pMyInfoIt = it._pMyInfoIt;
      return *this;
    }
    //creo funzioni che lavorano sugli iteratori
    /*
    bool operator==(const iterator& rhs)
    {
      return _pMyInfoIt == rhs._pMyInfoIt;

    }
    */
    friend bool operator== <T>(const typename myList::iterator& lhs,const typename myList::iterator& rhs);
    friend bool operator!= <T>(const typename myList<T>::iterator& lhs,const typename myList<T>::iterator& rhs);
  private:
    myInfo* _pMyInfoIt;
  };

  myList::iterator begin()
  {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    return iterator(_pInfo);
  }

private:
  class myInfo
  {
  public:
    myInfo(const T& data):_data(data),_pMyInfo(NULL)
    {}
  private:
    T _data;
    myInfo* _pMyInfo;
  };
  myInfo* _pInfo;
};


template <class T>
bool operator==(const typename myList<T>::iterator& lhs,const typename myList<T>::iterator& rhs)
{
  std::cout << __PRETTY_FUNCTION__ << std::endl;
  return lhs._pMyInfoIt == rhs._pMyInfoIt;
}

template <class T>
bool operator!=(const typename myList<T>::iterator& lhs,const typename myList<T>::iterator& rhs)
{
  return !(lhs == rhs);
}

int main(int argc,char** argv){
  myList<int> test;
  myList<int>::iterator it = test.begin();
  myList<int>::iterator it1 = test.begin();
  std::cout << typeid(it1).name() << std::endl;
  if(it == it1)
    std::cout << "EQUAL" << std::endl;
  return EXIT_SUCCESS;
}

thanks in advance

Community
  • 1
  • 1
GTA
  • 253
  • 4
  • 13

3 Answers3

0

Compiler can not deduce T. Change to:

template <class IT, class=typename IT::iterator_category>
bool operator==(const IT& lhs, const IT& rhs)

2nd template parameter does simple SFINAE, so that only iterators will match.

Leonid Volnitsky
  • 8,854
  • 5
  • 38
  • 53
0

Define the friend functions within the class body:

friend bool operator== <>(const typename myList<T>::iterator& lhs, const typename myList<T>::iterator& rhs)
{
    std::cout << __LINE__ << std::endl;
    return lhs._pMyInfoIt == rhs._pMyInfoIt;
}
friend bool operator!= <>(const typename myList<T>::iterator& lhs, const typename myList<T>::iterator& rhs)
{
    return !(lhs == rhs);
}

It should work.

pimanych
  • 21
  • 3
  • Can't this just be `friend bool operator==(const iterator& lhs...` if you're doing it that way? – user673679 Dec 16 '12 at 13:08
  • These are template functions, so they should look like friend bool operator!= <>(const typename myList::iterator& lhs, const typename myList::iterator& rhs) – pimanych Dec 16 '12 at 13:14
  • As I understand it, they're not. They're normal non-template functions injected into global scope as a result of the instantiation process (you get one for each myList::iterator). (Look up the Barton-Nackman trick). – user673679 Dec 16 '12 at 13:24
0

As pimanych says, declare the body of the friend function inside the class body:

    friend bool operator==(const iterator& lhs, const iterator& rhs)
    {
        return lhs._pMyInfoIt == rhs._pMyInfoIt;
    }
    friend bool operator!=(const iterator& lhs, const iterator& rhs)
    {
        return !(lhs == rhs);
    }

Note that these aren't really template functions, but are only declared when myList<T> (and myList<T>::iterator) is instantiated. You can check by attempting to compare a myList<int>::iterator and myList<float>::iterator - you should get a compiler error.

Look up the Barton-Nackman trick for more details.

user673679
  • 1,327
  • 1
  • 16
  • 35