Ответ 1
Рассмотрим этот код (A.h):
template <class T>
class A {
public:
T m_x;
friend bool operator<(const A & lhs, const A & rhs) {
return lhs.m_x < rhs.m_x;
}
};
И main.cpp:
#include "A.h"
namespace buddy {
bool operator<(const A<double> & lhs, const A<double> &rhs) {
return lhs.m_x > rhs.m_x;
};
}
using namespace buddy;
int main(int argc, char ** argv) {
A<double> a1;
A<double> a2;
a1 < a2;
return 0;
}
Этот код не компилируется:
main.cpp: 14: 5: ошибка: неоднозначная перегрузка для 'operator < (типы операндов - "A" и "A" ) a1 < а2;
Причина, конечно, в том, что оба оператора < являются точными совпадениями. С другой стороны, если мы изменим первый оператор < to (определяется вне класса):
template <class T>
bool operator<(const A<T> & lhs, const A<T> & rhs) {
return lhs.m_x < rhs.m_x;
}
Компилятор перестает жаловаться: теперь это конкуренция между точным соответствием и шаблоном функции, поэтому используется точное совпадение.
Если оператор < был определен таким образом, который вы предлагаете, не было бы разумного способа для пользователей std::vector переопределить поведение оператора <, не относящегося к специализации std::vector, что намного больше работает.
В заключение, стандартные авторы решили облегчить перегрузку оператора <, чем предоставить оператору < что может быть более полезным в определенных ситуациях. Я думаю, что они сделали правильный выбор.