7cows
7cows

Reputation: 5044

Linker error: Template relational operator

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

Answers (4)

Jesse Good
Jesse Good

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

Marcelo Cantos
Marcelo Cantos

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

Open AI - Opting Out
Open AI - Opting Out

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

IanPudney
IanPudney

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

Related Questions