Is_integral vs is_integer: один из них избыточен?
is_integral и is_integer кажется, отвечают на то же самое тем же способом.
Из ссылок на соответствующие страницы документации is_integral
, по-видимому, отсутствуют специализации для следующих типов
signed char
unsigned char
unsigned short
unsigned int
unsigned long
unsigned long long
Тем не менее, скомпилированный пример, показывает (разумеется) их идентичное поведение по этим типам:
#include <iostream>
#include <type_traits>
using namespace std;
int main()
{
cout << is_integral<signed char >::value << endl;
cout << is_integral<unsigned char >::value << endl;
cout << is_integral<unsigned short >::value << endl;
cout << is_integral<unsigned int >::value << endl;
cout << is_integral<unsigned long >::value << endl;
cout << is_integral<unsigned long long>::value << endl;
return 0;
}
Итак, если они тоже ведут себя одинаково, то в чем смысл вводить оба из них в С++ 11?
Итак, если они тоже ведут себя одинаково, то в чем смысл вводить их обоих в С++ 11?
Изменить: рефракции
Как отмечает Useless, фраза, включающая любые подписанные, неподписанные и cv-квалификационные варианты из страницы is_integral
doc, показывает, что даже их спецификации полный матч.
Ответы
Ответ 1
std::numeric_limits<T>::is_integer
не был введен С++ 11. Он был просто обновлен, чтобы использовать новый квалификатор constexpr
.
std::is_integral<T>
был введен С++ 11, и вы правы, он дает те же результаты. Что касается того, почему он был добавлен, возможно, потому, что интегральная или другая форма не является логически частью этого типа numeric_limits
?
Кажется, цель заголовка <type_traits>
состоит в том, чтобы собрать все помощники классификации типов в одном месте, в то время как старший numeric_limits
собирает только свойства, специфичные для, ну, чисел. Если бы numeric_limits<T>::is_integer
были устаревшими, была бы небольшая произвольная граница, тип которой жил в <type_traits>
и считался численным. Это вряд ли страшное дублирование, чтобы иметь его в обоих местах.
Ответ 2
Оба идентичны и будут обеспечивать одинаковые выходы.
Однако std::numeric_limits<T>::is_integer
существует с C98, а не С++ 11, тогда как std:: is_integral вводится как часть признаков типа С++ 11 (заголовок <type_traits>
)
Edit:
Как упоминалось @Useless, причиной введения std:: is_integral, вероятно, является желание перегруппировать все черты в <type_traits>
.
Ответ 3
Никто не упомянул о том, что std::is_integral
следует тому же стилю, что и другие С++ 11 UnaryTypeTraits для определения одного статического элемента данных, называемого value
. Это позволяет использовать его взаимозаменяемо, если требуется какой-либо унарный тип, например:
template<typename Cond1, typename Cond2>
using And = integral_constant<bool, Cond1::value && Cond2::value>;
Вы не можете использовать std::numeric_limits::is_integer
тем же способом, потому что он не соответствует тем же соглашениям, что и свойства С++ 11.
Разделение каждого признака на один тип с согласованными именами делает их более гибкими, чем признак, объединяющий несколько свойств вместе с непредсказуемыми именами.
Ответ 4
Вот исходное предложение добавить is_integral
в С++ 0x.
Они не ссылаются на перекрытие с std::numeric_limits<>::is_integer
, но я предполагаю, что желание было просто иметь все черты типа в одном очевидном месте.