Подтвердить что ты не робот

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, показывает, что даже их спецификации полный матч.

4b9b3361

Ответ 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, но я предполагаю, что желание было просто иметь все черты типа в одном очевидном месте.