Reputation: 5044
Why does this code give me a linker error and how do I fix it?
Undefined symbols for architecture x86_64: "operator==(foo const&, foo const&)", referenced from: _main in main.o ld: symbol(s) not found for architecture x86_64
template<typename T>
class foo {
//friends get access to the private member t
friend bool operator==(const foo<T> &lhs, const foo<T> &rhs);
T t;
};
template<typename T>
bool operator==(const foo<T> &lhs, const foo<T> &rhs) {
return lhs.t == rhs.t;
}
int main(int,char**) {
foo<int> f1, f2;
if (f1 == f2)
;
return 0;
}
Upvotes: 0
Views: 158
Reputation: 52365
Here is a fix of your code:
template<typename T>
class foo; // Forward declaration
template<typename T> // Need to define or declare this before the class
bool operator==(const foo<T> &lhs, const foo<T> &rhs) {
return lhs.t == rhs.t;
}
template<typename T>
class foo {
// Notice the little <> here denoting a specialization
friend bool operator==<>(const foo<T> &lhs, const foo<T> &rhs);
T t;
};
Upvotes: 3
Reputation: 185872
operator==
is a function template, but the friendship declaration doesn't reflect this. This is one way to fix it:
template <class U>
friend bool operator==(const foo<U> &lhs, const foo<U> &rhs);
One very minor glitch is that it gives operator==<int>
friend-access to foo<string>
. For this reason, I think @JesseGood's fix is cleaner, albeit (paradoxically) more verbose.
Upvotes: 1
Reputation: 24133
You need to specify the template types again, but different to the class template type:
template<typename V>
friend bool operator==(const foo<V> &lhs, const foo<V> &rhs);
Upvotes: 0
Reputation: 6021
When overloading operators, avoid using friend functions; you'll want to define your function as a public class member, and make it take only one argument (not two).
template<typename T>
class foo {
//public function allowing access to the private member t
public:
bool operator==( foo<T> &rhs)
{
return t == rhs.t;
}
private:
T t;
};
int main(int,char**) {
foo<int> f1, f2;
if (f1 == f2)
;
return 0;
}
Upvotes: -2