2014-01-12 2 views
6

Я использую Visual Studio 2010 и следующий код смутил меня немного:make_signed <unsigned long> :: type is int?

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

х будет иметь тип Int, но я ожидал бы долго. Я знаю, что int и long в VS10 являются 4-байтовыми целыми числами. Но даже если подписанный long вписывается в int, int для меня не является знаком целочисленного типа, соответствующего unsigned long. Поэтому мой вопрос: это ошибка/техническая неточность или технические характеристики стандарта позволяют этот результат?

+0

Я получаю 'long' на GCC 4.9.0, FWIW. –

+1

На моем VS2013 Express я также получаю 'long'. – DaBrain

+2

С VS2012, также 'long'. –

ответ

8

C++ 11 20.9.7.3 [meta.trans.sign] описывает make_signed:

If T имена (возможно, резюме квалифицированных) знаковый целочисленный тип (3.9.1), то членом TYPEDEF type должен называть тип T; в противном случае, если T называет (возможно, резюме квалифицированных) целое число без знака типа, то type должен назвать соответствующие целочисленный тип, с теми же CV-классификаторов, как T [курсив]; в противном случае type должен называть знак целочисленного типа с наименьшим размером (4.13), для которого sizeof(T) == sizeof(type), с теми же cv-квалификаторами, как T.

Требуется:T должно быть (возможно, резюме квалифицированных) интегрального типа или перечисления, но не bool типа.

Я хотел бы рассмотреть «соответствующий целочисленный тип» unsigned long быть long. Я не думаю, что есть много возможностей для интерпретации.

EDIT: no место для интерпретации, поскольку стандарт определяет «соответствующий тип целочисленного знака». 3.9.1/2 гласит:

Есть пять стандартных типов знаковое целое число: «signed char», «short int», «int», «long int», и «long long int». ...

и 3.9.1/3:

Для каждого из стандартных целочисленных типов подписаны, существует соответствующее (но разный) стандартного беззнаковое целое число типа: «unsigned char», «unsigned short int», «unsigned int», «unsigned long int» и «unsigned long long int», каждый из которых занимает один и тот же объем хранения и имеет те же требования к выравниванию (3.11), что и соответствующий тип целочисленного знака; то есть каждый тип целочисленного знака имеет то же представление объекта, что и его неподписанный целочисленный тип. ...

Соответствующий тип целочисленного знака unsigned long int, очевидно, long int.

+0

Согласен, как и GCC. –

+0

Кажется, это нерешенная проблема VS2010. Как я уже упоминал в своем комментарии выше, он исправлен, по крайней мере, в VS2013. Если кто-то хочет проверить VS2012, пожалуйста, оставьте комментарий, поскольку это все еще меня интересует. – DaBrain

0

МОЖЕТЕСЬ, что ваш тест может быть испорчен?Я не уверен, поскольку вы не указали код. Однако для такого теста НЕ используйте размер, чтобы определить, какой тип возвращается. Такой тест является неточным, если длинный может быть того же размера, что и int.

Например:

#include <type_traits> 
#include <iostream> 
#include <typeinfo> 

std::make_signed<unsigned long>::type x; 

int main() 
{ 
    std::cout<<(sizeof(x) == sizeof(int)); 
} 

является реализация определена и может возвращать истину, если долго тот же размер, что и междунар. В большинстве систем это вернет true.

Выполнение:

#include <type_traits> 
#include <iostream> 
#include <typeinfo> 

std::make_signed<unsigned long>::type x; 

int main() 
{ 
    std::cout<<typeid(x).name(); 
} 

напечатает L если x является long и он будет печатать I если x является int.

+0

Я не использовал размер, чтобы определить тип. Как я уже упоминал в вопросе в VS2010 int и long, оба 4-байтовых целых числа в любом случае смотрят [link] (http://msdn.microsoft.com/en-us/library/s3f49ktz%28v=vs.100%29.aspx). Это была IDE Visual Studio, которая сказала мне, что это int, и поскольку это реализация только для заголовка, я мог бы также проверить код. Немного изменил пример, чтобы сделать его более очевидным. – DaBrain

Смежные вопросы