tags:

views:

76

answers:

3

I try to implement the following function :

template<typename T>
class a
{
private:
    T var;
    friend bool operator==(const a<T> &, const a<T> &);
};

template<typename T> inline bool operator==(const a<T> &r1, const a<T> &r2)
{
    return r1.var==r2.var;
}

int main () {
    a<int> var0;
    a<int> var1;
    var0 == var1;
}

However, I get

main.obj : error LNK2001: unresolved external symbol "bool __cdecl operator==(class a<int> const &,class a<int> const &)" (??8@YA_NABV?$a@H@@0@Z)

under VC++ 2008

May I know how I can fix the linking error?

+3  A: 

What you have declares the friend op== as a non-template, but you implement it as a template. That is why the definition is not found when linking.

How I usually overload op== for class templates:

template<class T>
struct A {
  friend bool operator==(A const& a, A const& b) {
    return a.var == b.var;
  }
private:
  T var;
};
Roger Pate
And if for some reason you have to define operator== outside the class (perhaps to break a circular dependency with some other class), then you can declare it as `template <typename S> friend bool operator==(A<S> const`, then define it as a template.
Steve Jessop
+1  A: 
template<typename T>
class Sample
{
public:
    template<typename T> friend bool operator==(const Sample<T>& lhs, const Sample<T>& rhs);
private:
     T val_;
};

template<typename T>
bool operator==(const Sample<T>& lhs, const Sample<T>& rhs)
{
    return lhs.val_ == rhs.val_;
}

int main()
{
    Sample<char*> s1;
    Sample<char*> s2;
    cout << (s1 == s2) << endl;
}
Jagannath
operator== function shall access to member of the template class.
Yan Cheng CHEOK
My previous sample was just a demo method. Now, I edited to access the member variable.
Jagannath
Nice. But under VC6++, it will give compile error : conditional expression of type 'void' is illegal
Yan Cheng CHEOK
A: 

Is there any difference between the following two implementations?

1)

template <class T>
class a ;
template <class T>
bool operator==(const a<T> &, const a<T> &);
template<typename T>
class a
{
private:
    T var;
    friend bool operator== <>(const a<T> &, const a<T> &);
};

template<typename T> inline bool operator==(const a<T> &r1, const a<T> &r2)
{
    return r1.var==r2.var;
}

2)

template<typename T>
class a
{
private:
    T var;
    template <class T1>
    friend bool operator==(const a<T1> &, const a<T1> &);
};

template<typename T> inline bool operator==(const a<T> &r1, const a<T> &r2)
{
    return r1.var==r2.var;
}

If so, which one is preferred?

hype
see comments to the first answer, and don't post questions as answers ;>
Kornel Kisielewicz
Sure :) but i'm afraid that it will be marked as duplicate. Anyways, i didn't find answer to my question in the comments (to first answer)And in fact the answer to OP's question is also there in my post
hype
There's a difference in what has friendship (one vs all specializations), and I think you may need to specify the template parameter in #1, but not sure. As to posting a possible duplicate: try it and see. Obviously there's something different, or you wouldn't have asked, so emphasize that difference, include a mention of the related question, and the community will let you know.
Roger Pate
Thanks Roger...however i didn't understand that (what has friendship (one vs all specializations)) :) , may be i'll post this as u have suggested. And template parameter is not required in the #1 implementation.
hype