7cows
7cows

Reputation: 5044

Relational operators on a class template

This will not work

template<typename T>
struct foo {
  T t;
};
bool operator==(const foo &lhs, const foo &rhs) { //error, requires template arg
  return lhs.t == rhs.t;
}

Is this the correct way to solve this? I want define also the operators <,>,<=,>=,!= so doing template<typename T> on all of them would be lengthy.

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

Upvotes: 0

Views: 463

Answers (2)

TemplateRex
TemplateRex

Reputation: 70556

There are two solutions: you can define them as const member functions inside the class

template<typename T>
struct foo {
  T t;

  bool operator==(const foo &lhs, const foo &rhs) const { return lhs.t == rhs.t; }
  // same for the other relational operators
};

This works because inside the class you can use foo as a shorthand for foo<T>.

An alternative is to define them as friend non-member functions inside the class

template<typename T>
class foo {
  T t;

  friend bool operator==(const foo &lhs, const foo &rhs) const { return lhs.t == rhs.t; }
  // same for the other relational operators
};

If you define t as a private member, then you actually need to make operator== a friend function in order to let it gain access. Note however, that this will have the side-effect as injecting them as non-member non-template functions in the surrounding namespace. This has some consequences for argument-dependent name lookup.

Upvotes: 2

Julien Lopez
Julien Lopez

Reputation: 1021

if you don't care about implicit conversions, you can set them as member functions, so you won't have to retype it each time.

but if you have to define them as free functions, I'm afraid you don't have a choice.

Upvotes: 0

Related Questions