Реляционные операторы на шаблоне класса

Это не будет работать

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

Это правильный способ решить эту проблему? Я хочу определить также операторы <,>,<=,>=,!= Так делать template<typename T> на всех них было бы долго.

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;
}

2 ответа

Решение

Есть два решения: вы можете определить их как постоянные функции-члены внутри класса

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
};

Это работает, потому что внутри класса вы можете использовать foo как сокращение для foo<T>,

Альтернативой является определение их как дружественных не-членских функций внутри класса.

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
};

Если вы определите t как частный член, то вам действительно нужно сделать operator== friend функция, чтобы позволить ему получить доступ. Однако обратите внимание, что это будет иметь побочный эффект, заключающийся в том, что они внедряются как функции, не являющиеся членами-не шаблонами, в окружающее пространство имен. Это имеет некоторые последствия для поиска имени в зависимости от аргумента.

Если вам не нужны неявные преобразования, вы можете установить их как функции-члены, поэтому вам не придется каждый раз вводить их заново.

но если вам нужно определить их как свободные функции, боюсь, у вас нет выбора.

Другие вопросы по тегам