Нет прямого способа заменить operator <<
, но у вас есть несколько вариантов. Во-первых, вы можете просто написать свою собственную функцию для печати комплексных чисел:
template <typename T> void PrintComplex(const complex<T>& c) {
/* ... */
}
Если вы все еще хотите использовать синтаксис nice stream, то вы могли бы сделать один трюк - создать класс-оболочку, который обернет complex
, а затем определит свой собственный operator <<
, который распечатывает его другим способом. Например:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
complex<T> c;
};
Если у вас есть это, вы можете написать что-то вроде
cout << ComplexPrinter<double>(myComplex) << endl;
Вы можете сделать это еще чище, написав функцию, подобную этой, чтобы обернуть объект для вас:
template <typename T>
ComplexPrinter<T> wrap(const complex<T>& c) {
return ComplexPrinter<T>(c);
}
Затем вы можете написать
cout << wrap(myComplex) << endl;
Что не идеально, но довольно хорошо.
Одна вещь, о которой следует упомянуть в вышеупомянутой оболочке, это то, что в ней установлен неявный конструктор преобразования, позволяющий вам преобразовывать complex<T>
с в ComplexPrinter<T>
с. Это означает, что если у вас есть vector< complex<T> >
, вы можете распечатать его, используя свой код, позвонив по номеру
vector< complex<double> > v = /* ... */
copy (v.begin(), v.end(), ostream_iterator< ComplexPrinter<double> >(cout, " "));
При выводе конструктор неявного преобразования преобразует ваши complex<double>
s в оболочки, а ваш пользовательский код будет печатать за вас.
Если вы хотите быть очень предприимчивым и проявлять осторожность, вы можете даже написать класс, чтобы он просто сохранял ссылку на оригинал complex
, как показано здесь:
template <typename T> class ComplexPrinter {
public:
/* Conversion constructor allows for implicit conversions from
* complex<T> to ComplexPrinter<T>.
*/
ComplexPrinter(const complex<T>& value) : c(value) {
// Handled in initializer list
}
/* Output the complex in your own format. */
friend ostream& operator<< (ostream& out, const ComplexPrinter& cp) {
/* ... print in your own format ... */
}
private:
const complex<T>& c;
};
Это полностью исключает любое копирование и просто делает обертку тонкой фанерой вокруг настоящего complex
. (Не каламбур предназначен). Вам следует быть очень осторожным, если вы сделаете это, чтобы не пропустить эти объекты через границы области видимости, где исходные объекты выходят из области видимости, но если это то, что вам нужно, это может сработать просто замечательно.
Надеюсь, это поможет!