Make_signed <unsigned long> :: type is int?

I am using Visual Studio 2010, and the following code confused me a bit:

#include<type_traits> auto x = std::make_signed<unsigned long>::type(); 

x will be of type int, but I would have expected a long time. I know that int and long in VS10 are 4 byte integers. But even if the signed long fits into int, int for me is not a sign of the integer type corresponding to unsigned long. So my question is: is this a mistake / technical inaccuracy or do standard specifications allow this result?

+6
source share
2 answers

C ++ 11 20.9.7.3 [meta.trans.sign] describes make_signed :

If T calls (possibly cv-qualified) an integer type (3.9.1), then the member of typedef type must indicate the type of T ; otherwise , if T calls (possibly cv-qualified) an unsigned integer type, then type must name the corresponding signed integer type with the same cv-qualifiers as T [italics]; otherwise, type must indicate an integer type with the lowest rank value (4.13) for which sizeof(T) == sizeof(type) , with the same cv-qualifiers as T

Required: T must be an (possibly cv-qualified) integral type or enumeration, but not a bool type.

I would consider the "corresponding signed integer type" unsigned long as long . I do not think there is much room for interpretation.

EDIT: There is no room for interpretation as the standard defines “the appropriate type of integer character”. 3.9.1 / 2:

There are five standard standard integer types: " signed char ", " short int ", " int ", " long int " and " long long int " ....

and 3.9.1 / 3:

For each standard signed integer type, there is a corresponding (but different) standard unsigned integer type: " unsigned char ", " unsigned short int ", " unsigned int ", " unsigned long int " and " unsigned long long int ", each of which occupies the same storage volume and has the same alignment requirements (3.11) as the corresponding type of integer character; that is, each type of integer character has the same representation of the object as its unsigned integer type ....

The corresponding integer character type is unsigned long int , obviously long int .

+8
source

Perhaps your test might be ruined? I am not sure, since you did not specify the code. However, for such a test, DO NOT use size to determine which type is being returned. Such a test is inaccurate when a long one can have the same size as an int.

For instance:

 #include <type_traits> #include <iostream> #include <typeinfo> std::make_signed<unsigned long>::type x; int main() { std::cout<<(sizeof(x) == sizeof(int)); } 

an implementation is defined and can return true if long is the same size as int. On most systems, this will return true.

Doing:

 #include <type_traits> #include <iostream> #include <typeinfo> std::make_signed<unsigned long>::type x; int main() { std::cout<<typeid(x).name(); } 

will print L if x is long , and it will print I if x is int .

0
source

All Articles