ostream: как вызываются функции для этого связанного вывода? - PullRequest
1 голос
/ 06 августа 2020

Может ли кто-нибудь объяснить, как следующий код iostream cout оценивается с каждой конкретной c функцией, включая ее объявление? Кроме того, как манипулятор hex изменяет флаги потока (я предполагаю, что он вызывает ios.flags()). Например, я смотрю на функции-члены ostream и не-функции-члены и не понимаю, что именно вызывается, и порядок оценки (я думаю, что нет определенного порядка).

#include <iostream>
using namespace std;

int main()
{
    int v = 0xFF;
    cout << "0x" << hex << v << endl;

    return 0;
}

1 Ответ

2 голосов
/ 06 августа 2020

std::hex и std::endl - автономные функции, которые принимают std::ios_base& и std::basic_ostream& в качестве входных данных, соответственно:

std::ios_base& hex( std::ios_base& str );
template< class CharT, class Traits >
std::basic_ostream<CharT, Traits>& endl( std::basic_ostream<CharT, Traits>& os );   

Эти функции при необходимости управляют данным потоком:

  • std::hex() вызывает метод потока setf(), чтобы включить на нем флаг std::ios_base::hex.
  • std::endl() записывает разрыв строки в поток и затем очищает поток.

std::basic_ostream имеет нестатические c элементы operator<< перегрузки, которые принимают на вход такие функции:

basic_ostream& operator<<(
    std::ios_base& (*func)(std::ios_base&) );
basic_ostream& operator<<(
    std::basic_ostream<CharT,Traits>& (*func)(std::basic_ostream<CharT,Traits>&) );

Эти operator<< перегрузки просто вызовите данную функцию с *this в качестве входных данных, а затем верните *this вызывающей стороне.

Существует также нестатическая c член operator<< перегрузка для принятия int как input:

basic_ostream& operator<<( int value );

Эта перегрузка записывает значение int в this, а затем возвращает *this вызывающей стороне.

Однако нестандартных * 1061 нет. * member operator<< перегрузка для принятия строкового литерала в качестве входных данных, но для этого существуют автономные перегрузки, не являющиеся членами operator<<:

* 10 45 *
template< class CharT, class Traits >
basic_ostream<CharT,Traits>& operator<<( basic_ostream<CharT,Traits>& os,
                                         const char* s );
template< class Traits >
basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os,  
                                        const char* s );

Эти перегрузки записывают данные char* в os, а затем возвращают os вызывающему.

Итак, выражение:

cout << "0x" << hex << v << endl;

В итоге оценивается так:

operator<<(cout, "0x").operator<<(hex).operator<<(v).operator<<(endl);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...