Не могу понять как объект
fpos
взаимодействует с потоком. В файле
iosfwd.h описан класс
fpos
.
Кликните здесь для просмотра всего текста
C++ |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
| // STREAM POSITIONING TYPES (from <streambuf>)
using streamoff = long long;
using streamsize = long long;
// CLASS TEMPLATE fpos (from <streambuf>)
template<class _Statetype>
class fpos
{ // store arbitrary file position
public:
/* implicit */ fpos(streamoff _Off = 0)
: _Myoff(_Off), _Fpos(0), _Mystate()
{ // construct with stream offset
}
fpos(_Statetype _State, fpos_t _Fileposition)
: _Myoff(_Fileposition), _Fpos(0), _Mystate(_State)
{ // construct with conversion state and C file position
}
_NODISCARD _Statetype state() const
{ // return conversion state
return (_Mystate);
}
void state(_Statetype _State)
{ // set conversion state
_Mystate = _State;
}
operator streamoff() const
{ // return offset
// TRANSITION, ABI: We currently always set _Fpos to 0 but older .objs containing old basic_filebuf
// would set _Fpos.
return (_Myoff + _Fpos);
}
#ifndef _REMOVE_FPOS_SEEKPOS
_DEPRECATE_FPOS_SEEKPOS fpos_t seekpos() const noexcept
{
return {};
}
#endif // _REMOVE_FPOS_SEEKPOS
_NODISCARD streamoff operator-(const fpos& _Right) const
{ // return difference of file positions as an offset
return (static_cast<streamoff>(*this) - static_cast<streamoff>(_Right));
}
fpos& operator+=(streamoff _Off)
{ // add offset
_Myoff += _Off;
return (*this);
}
fpos& operator-=(streamoff _Off)
{ // subtract offset
_Myoff -= _Off;
return (*this);
}
_NODISCARD fpos operator+(streamoff _Off) const
{ // return this + offset
fpos _Tmp = *this;
_Tmp += _Off;
return (_Tmp);
}
_NODISCARD fpos operator-(streamoff _Off) const
{ // return this - offset
fpos _Tmp = *this;
_Tmp -= _Off;
return (_Tmp);
}
_NODISCARD bool operator==(const fpos& _Right) const
{
return (static_cast<streamoff>(*this) == static_cast<streamoff>(_Right));
}
template<class _Int,
enable_if_t<is_integral_v<_Int>, int> = 0>
_NODISCARD friend bool operator==(const fpos& _Left, const _Int _Right)
{
return (static_cast<streamoff>(_Left) == _Right);
}
template<class _Int,
enable_if_t<is_integral_v<_Int>, int> = 0>
_NODISCARD friend bool operator==(const _Int _Left, const fpos& _Right)
{
return (_Left == static_cast<streamoff>(_Right));
}
_NODISCARD bool operator!=(const fpos& _Right) const
{
return (static_cast<streamoff>(*this) != static_cast<streamoff>(_Right));
}
template<class _Int,
enable_if_t<is_integral_v<_Int>, int> = 0>
_NODISCARD friend bool operator!=(const fpos& _Left, const _Int _Right)
{
return (static_cast<streamoff>(_Left) != _Right);
}
template<class _Int,
enable_if_t<is_integral_v<_Int>, int> = 0>
_NODISCARD friend bool operator!=(const _Int _Left, const fpos& _Right)
{
return (_Left != static_cast<streamoff>(_Right));
}
private:
streamoff _Myoff; // stream offset
fpos_t _Fpos; // TRANSITION, ABI. C file position, not currently used
_Statetype _Mystate; // current conversion state
};
using streampos = fpos<_Mbstatet>;
using wstreampos = streampos; |
|
После описания класса
fpos
есть такая строка
C++ |
1
| using streampos = fpos<_Mbstatet>; |
|
Насколько я понимаю, если где-то в коде написано
streampos
, то это то же самое что и
fpos<_Mbstatet>
, то есть
streampos
это по существу тип объекта класса
fpos
.
К сожалению, пока не знаю шаблонов, но сам класс
fpos
является шаблонным
C++ |
1
2
3
4
5
| template<class _Statetype>
class fpos
{
// this is code
}; |
|
Получается, что когда в коде будет использоваться
streampos
, параметр шаблона
class _Statetype
будет
_Mbstatet
, которая представляет из себя такую структуру
C++ |
1
2
3
4
5
6
7
| typedef struct _Mbstatet
{ // state of a multibyte translation
unsigned long _Wchar;
unsigned short _Byte, _State;
} _Mbstatet;
typedef _Mbstatet mbstate_t; |
|
У объекта
fpos
такие данные
C++ |
1
2
3
4
| private:
streamoff _Myoff; // stream offset
fpos_t _Fpos; // TRANSITION, ABI. C file position, not currently used
_Statetype _Mystate; // current conversion state |
|
Его состояние имеет тип
_Statetype
, то есть при использовании
streampos
состояние хранится в структуре
_Mbstatet
.
Также у объекта есть неявный и явный конструкторы
C++ |
1
2
3
4
5
6
7
8
9
10
| public:
/* implicit */ fpos(streamoff _Off = 0)
: _Myoff(_Off), _Fpos(0), _Mystate()
{ // construct with stream offset
}
fpos(_Statetype _State, fpos_t _Fileposition)
: _Myoff(_Fileposition), _Fpos(0), _Mystate(_State)
{ // construct with conversion state and C file position
} |
|
Они оба почти идентичны,
_Fpos
у обоих
0
,
_MyOff
по умолчанию
0
либо передать в него некоторый
Fileposition, тип
fpos_t
определен в
stdio.h как
C++ |
1
| typedef __int64 fpos_t; |
|
то есть по сути
long long
Но с
_Mystate
уже не так очевидно, в неявном конструкторе
_Mystate()
непонятно чем инициализируется поле, в явном конструкторе получается что помимо
Fileposition при создании объекта
fpos
надо передать ещё и структуру типа
_Mbstatet
.
Например у меня есть такой код
C++ |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| #include <iostream>
#include <fstream>
int main() {
std::ifstream inputFile("test.txt");
if (inputFile.is_open()) {
/////////
char ch;
inputFile.get(ch);
inputFile.putback(ch);
/////////
/*Указатель на файловый буфер*/
std::streambuf* pbuf = inputFile.rdbuf();
/*Количество символов в этом буфере*/
std::streamsize size = pbuf->in_avail();
std::cout << size << std::endl;
}
return 0;
} |
|
В файле
test.txt написано слово
Abracadabra
, т.е. он содержит 11 символов. Если закомментировать
C++ |
1
2
3
| char ch;
inputFile.get(ch);
inputFile.putback(ch); |
|
то переменная
size
будет равна
0
. Не понимаю почему так происходит, но самое главное не понимаю на каком этапе "вылазит" объект
fpos
- он является аргументом какой-то глубокой функции или как? Проваливался по исходникам, но так и не увидел взаимодействия.