I have in my C++ program the lines
unsigned char c2;
in.get(c2);
Everything worked fine, but then I switched to the newest GNU compiler
(ver 3.1) and it said
no matching function for call to `std::basic_istream<char,std::char_traits<char> >::get(unsigned char&)'
c:/djgpp/lang/cxx-v31/bits/istream.cc:513: candidates are: [...]
std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT,
_Traits>::get(_CharT&) [with _CharT = char, _Traits = std::char_traits<char>]
So it works with normal 'char', but not with 'unsigned char'. It's a
template, so why can't the compiler generate the code for 'unsigned
char'? (Which it did, in the older version.)
Tschoe,
Torsten.
[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]
> Halloechen!
>
> I have in my C++ program the lines
>
> unsigned char c2;
> in.get(c2);
>
> Everything worked fine, but then I switched to the newest GNU compiler
> (ver 3.1) and it said
> [snip]
Well if you don't need signed chars in your program and there is a
compiler switch [argument to compiler] that tells the compiler to use
unsigned chars for chars, then this may be the easiest solution. {beware
such an option may require some recompilation of the standard library
library file].
If the standard library contains a generic std::char_traits template,
see the header <string>,
then using basic_ifstream<unsigned char> and basic_istream<unsigned
char> should do the trick.
If there is only template <class charT> class char_traits; then you
need to write an std::char_traits<unsigned char> not extremely difficult
but time consuming...
Not really sure about gcc 3's implimentation of the standard C++
library.
> It's a template, so why can't the compiler generate the code for
> 'unsigned char'? (Which it did, in the older version.)
--
- Yannick Loitiere -
Hi! I'm a .signature virus! Copy me into your ~/.signature to help me
spread!
Because get() is a member function of a class template, but it's not a
template member function.
Look at the error message again. The parameter type of get() is
'_CharT &', where _CharT is the first type parameter of the
basic_istream class template. The message shows that you instantiated
basic_istream with 'char' as the first type argument (your 'in' object
is probably of a predefined stream type like ifstream or
istringstream); therefore, get() expects a 'char &'.
Bence Kodaj
> > I have in my C++ program the lines
> > unsigned char c2;
> > in.get(c2);
> > Everything worked fine, but then I switched to the newest GNU
> > compiler (ver 3.1) and it said
> > [snip]
> Well if you don't need signed chars in your program and there is
> a compiler switch [argument to compiler] that tells the compiler to
> use unsigned chars for chars, then this may be the easiest
> solution. {beware such an option may require some recompilation of
> the standard library library file].
That doesn't change anything. The type char is still a different type
than unsigned char (just as it is a different type than signed char
otherwise).
Logically, I can't imagine anyone having the option for plain char to
be unsigned not using it, systematically. It is a lot less subject to
error.
> If the standard library contains a generic std::char_traits
> template, see the header <string>, then using
> basic_ifstream<unsigned char> and basic_istream<unsigned char>
> should do the trick.
That sort of depends on what the generic class contains. I have heard
of people having problems with it -- if I remember correctly, both g++
and VC++ (Dinkumware) have a generic version, but the two have
different behavior. (Since the standard is sigularly silent about
this, both are "right".) And you cannot provide your own
specialization.
With a modern library, of course, you will probably also run into
problems with codecvt -- there may not be a generic version of that,
either.
In practice, the result of all of these constraints is that you cannot
instantiate the iostream templates except for char, wchar_t and user
defined POD types.
> If there is only template <class charT> class char_traits; then you
> need to write an std::char_traits<unsigned char> not extremely difficult
> but time consuming...
And illegal. (Although I'll admit that it is what I recommended in
the case above.)
--
James Kanze mailto:jka...@caicheuvreux.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(0)69 63198627
Recently I came across a problem where I had two compilers one which had
plain char signed and the other unsigned. It then had the typedefs
typedef UINT8 unsigned char;
typedef CHAR char;
typedef INT8 char;
so in one compiler INT8 was not actually signed leading to various obscure
looping bugs. Initially I tried to fix this by changing the typedef for
INT8 to a signed char. This broke a lot of code which assumed that INT8 and
plain char were equivalent (this is the default in microsoft C++ so is often
considered a de facto standard).
What I then found is that strictly there are 3 char types. It does not
matter what way you have defined plain char to be in your compiler, it is
still not equivalent to either signed or unsigned. This really matters when
dealing with pointers in C++.
However most compilers are not quite this choosy. Personally I like to use
plain char for real strings of characters, UINT8 for hardware access where
it is needed, and INT8 very rarely.
My solution for your case is to use a reinterpret_cast. I really wish there
was an alternative for the 3 char pointer types (as I believe they are
guaranteed to be the same size).
Matthew