Как происходит цепочка операторов в С++?
У меня есть основной вопрос на С++.
#include <iostream>
using namespace std;
int main() {
int a = 255;
cout << hex << a << endl; // <-----
}
В приведенном выше коде, как заключен оператор std::cout
?
Я понимаю, что реализация cout
вернет ссылку на объект cout
, чтобы разрешить цепочку, поэтому она должна выполняться как:
(((cout << hex) << a) << endl)
то есть. эквивалентно их, чтобы
-
cout << hex
-
cout << a
-
cout << endl
Но это не может быть так, потому что некоторая ценность a
должна быть преобразована в форму hex
!
Как операторы фактически привязаны компилятором, чтобы сделать преобразование?
Ответы
Ответ 1
Вот как обычно реализуется hex
:
inline ios_base&
hex(ios_base& __base)
{
__base.setf(ios_base::hex, ios_base::basefield);
return __base;
}
Как вы можете видеть, hex
не выполняет никакого преобразования сам по себе: вместо этого он устанавливает опцию в базовом потоке для использования hex для печати чисел, переданных в нее в более поздней точке.
EDIT (в ответ на комментарий)
Как правильно отмечает хаммар, другая часть головоломки - это то, как вызывается hex(ios_base& __base)
. Существует перегрузка оператора <<
с этой сигнатурой:
ostream& operator <<(ostream& (*)(ostream&))
Эта перегрузка является важной деталью реализации манипуляторов потока. Именно эта перегрузка вызывает hex
и позволяет ей делать свою "магию" (что, конечно же, больше не должно звучать как волшебство).
Ответ 2
У вас все в порядке, это точно, как это работает. hex
имеет специальный тип, который изменяет внутреннее состояние объекта cout
при передаче его функции operator<<
. Затем внутреннее состояние определяет, как обрабатываются любые будущие значения, прошедшие через cout
через operator<<
.
std::hex
оказывается функцией. cout << hex
не вызывает функцию hex как таковой, однако: она передает указатель на шестнадцатеричную функцию на перегрузку operator<<
для ostream
, которая принимает указатели на функции с определенной сигнатурой. hex()
затем вызывается изнутри реализации оператора через этот указатель функции и изменяет объект ostream
оттуда, насколько я знаю.
Ответ 3
std::hex
фактически устанавливает флаг внутри объекта std::cout
, который будет придерживаться до reset IIRC. Сами operator<<
оцениваются слева направо, поэтому ваши парнеры правильны.
Ответ 4
С моей точки зрения hex - это просто объект пакета, который имеет побочный эффект для объекта cout. После этого cout будет выводить только шестнадцатеричные значения.
Ответ 5
std:: hex - это функция, которая изменяет состояние объекта std:: ostream. http://www.cplusplus.com/reference/iostream/manipulators/hex/