From the C ++ standard
3.9.1 Basic types [basic.fundamental]
Objects declared as characters (char) must be large enough to hold any element of the base implementation character set. If a character from this set is stored in a character object, the integer value of this character object is equal to the value of the one-character literal form of this character. The implementation is determined whether the char object can contain negative values. Symbols may be explicitly declared unsigned or signed. Regular char, signed char and unsigned char are three different types . A char, signed char and unsigned char occupy the same number of stores and have the same alignment requirements (basic.types); that is, they have the same representation of the object. For character types, all bits of the object's representation participate in the value representation. For unsigned character types, all possible bit patterns for representing values โโrepresent numbers. These requirements are not suitable for other types. In any particular implementation, a simple char object can take the same values โโas a signed char or unsigned char; which one is determined by implementation.
char , unsigned char and signed char are thus three different types, and boost::is_integral should be specialized for these three types. You can expect gcc 4.4.7 or the OP environment to ignore this, and I will look for an explanation. Please see this interim answer as an extended comment on the OP question.
EDIT : cannot play
System: Red Hat 6
$ uname -a Linux ysc 2.6.32-504.8.1.el6.x86_64
Compiler:
$ g++ --version g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16)
A source:
$ cat main.cpp #include <iostream> template<typename T> struct trait { static const int value = 0; }; template<> struct trait<char> { static const int value = 1; }; template<> struct trait<signed char> { static const int value = 2; }; template<> struct trait<unsigned char> { static const int value = 3; }; int main() { std::cout << "int:, " << trait<int>::value << "!\n"; std::cout << "char:, " << trait<char>::value << "!\n"; std::cout << "unsigned char:, " << trait<unsigned char>::value << "!\n"; std::cout << "signed char:, " << trait<signed char>::value << "!\n"; }
Compilation:
$ g++ -Wall -Wextra main.cpp
Run:
$ ./a.out int:, 0! char:, 1! unsigned char:, 3! signed char:, 2!
What does he create in the OP environment?
source share