The declaration of template std::basic_ifstream
is:
template<
class CharT,
class Traits = std::char_traits
> class basic_ifstream;
The C++03 Standard (21.1/1) requires the library to define specializations
of std::char_traits
for CharT
= char
, wchar_t
.
The C++11 Standard (C++11 21.2/1) requires the library to define specializations
of std::char_traits
for CharT
= char
,char16_t
,char32_t
,wchar_t
.
If you instantiate std::basic_ifstream
with Other
not one of
the 2[4] types nominated by the Standard to which you are compiling then
the behaviour will be undefined, unless you yourself
define my_char_traits
as you require and then instantiate
std::basic_ifstream>
.
CONTINUED in response to OP's comments.
Requesting an std::char_traits
will not provoke template instantiation
errors: the template is defined so that you may specialize it, but the
default (unspecialized) instantiation is very likely to be wrong for Other
or indeed for any given CharT
, where wrong means does not satisfy the
the Standard's requirements for a character traits class per C++03 § 21.1.1/C++11 § 21.2.1.
You suspect that a typedef might thwart the choice of a template specialization
for the typedef
-ed type, i.e. that the fact that uint8_t
and int8_t
are typedefs for fundamentals character types might result in std::basic_ifstream
not being the same as std::basic_ifstream
, where FCT
is the aliased fundamental character type.
Forget that suspicion.typedef
is transparent. It seems you believe one of
the typedefs int8_t
and uint8_t
must be char
, in which case - unless
the typedef was somehow intefering with template resolution -
one of the misbehaving basic_ifstream
instantiations you have tested would
have to be std::basic_ifstream
But what about the fact that typedef char byte
is harmless? That belief that
either int8_t
or uint8_t
= char
is false. You will find that int8_t
is an alias for signed char
while uint8_t
is an alias for unsigned char
.
But neither signed char
nor unsigned char
is the same type as char
:
C++03/11 § 3.9.1/1
Plain char, signed char, and unsigned char are three distinct types
So both char_traits
and char_traits
are default,
unspecialized, instantiations of template char_traits
and you have
no right to expect that they fulfill that Standard's requirements of
character traits.
The one test case in which you found no misbehaviour was for byte
= char
.
That is because char_traits
is a Standard specialization provided
by the library.
The connection between all the misbehaviour you have observed and the
types that you have substituted for SOMECAST
in:
std::cout << (SOMECAST)buff; // <------- interesting
is none. Since your testfile contains ASCII text, basic_ifstream
is the one and only instantiation of basic_ifstream
that the Standard warrants
for reading it. If you read the file using typedef char byte
in your program
then none of the casts that you say you substituted will have an unexpected
result: SOMECAST
= char
or unsigned char
will output a
, and
SOMECAST
= int
or unsigned int
will output 97
.
All the misbehaviour arises from instantiating basic_ifstream
with CharT
some type that the Standard does not warrant.