Перегрузка оператора может быть хорошей или плохой вещью.Хорошо, когда это приводит к более простому виду кода.Плохо, когда это приводит к тому, что авторы перезагружаются с неверной семантикой (но это решение компилируется) или когда интуитивный способ использования оператора приводит к крайне неэффективному коду.
Обратите внимание, что последнее утверждение может применяться к std :: stringКроме того, что может потенциально сделать большое количество копий, и именно поэтому стандарт C ++ 03 гласит, что строка не должна храниться внутри в непрерывном буфере (в старые времена они использовали ссылки «копировать при записи»)и может хранить такие ссылки на обе строки, соединяемые до тех пор, пока они не потребуются. Впоследствии было установлено, что он не является потокобезопасным, и его создание было более затратным, чем простое копирование буфера, поэтому теперь они копируются каждый раз и снова неэффективны).
(Обратите внимание, что стандарт C ++ 11, который распознает многопоточность и атомарные проблемы, гарантирует, что базовый элемент должен быть непрерывным и завершаться нулем, чтобы сделать операции чтения безопасными).
Правильная сигнатура оператора + (вдела все одинаковыtype) выглядит следующим образом:
T operator+( const T&, const T& );
В качестве функции-члена это будет:
class T
{
// make public if necessary
T operator+( const T& rhs ) const;
};
Вы можете автоматически реализовывать оператор + как шаблон всякий раз, когда оператор + = доступен с
template<typename T, typename R>
T operator+( const T& lhs, const R& rhs )
{
T copy(lhs);
return copy += rhs;
}
Если вы хотите объявить перегруженный оператор вашего шаблона другом, это правильный способ сделать это.Я покажу это с помощью оператора << </p>
// first some forward declarations, assume ostream already declared with #include <iosfwd> minimum
template< typename T > class Forest;
template< typename T > std::ostream & operator<<( std::ostream & os, const Forest<T> & for );
template< typename T> class Forest
{
friend std::ostream& operator<< <>( std::ostream&, const Forest<T> & );
//rest of class Forest
};
template< typename T >
std::ostream & operator<<( std::ostream& os, const Forest<T> & forest )
{
// implement
return os;
}
. Вы примените аналогичную технику к любой другой внешней функции, которую вы хотите объявить в качестве друга в своем классе, например
- Forwardобъявить ваш класс как шаблон
- Заблаговременно объявить метод как функцию шаблона
- Сделать функцию другом с помощью <> перед открывающими скобками, обозначающими параметры
- Реализовать функциюпосле вашего класса.