On-line: гостей 0. Всего: 0 [подробнее..]
Программисты всех стран, объединяйтесь!

АвторСообщение



ссылка на сообщение  Отправлено: 26.08.12 18:52. Заголовок: Характеристика типа (type trait)) is_bool в C++


Если сделать в интернет поиск по ключевому слову is_bool, то вы получите множество ссылок на сайты, связанные с языком программирования PHP. Эта функция возвращает значение true, если ее аргумент имеет булевый или, по-другому, логический тип.

Естественно было бы ожидать, что такая же функция имеется в стандарте С++ в заголовочном файле <type_traits>. Но, увы, такой функции в стандарте С++ нет.

Сначала поставим вопрос, а нужна ли такая функция в стандарте в С++?

Хотя тип bool относится к целочисленным типам, это особый тип, отличающийся от других целочисленных типов, так как для него не имеет смысла выполнение многих арифметических операций таких, как, к примеру, деление или взятие остатка от деления. Поэтому, когда создается шаблонный класс, который в качестве параметра шаблона должен иметь целочисленный тип и выполнять операции над объектами этого типа, то тип bool обычно исключается из числа допустимых типов для специализации такого класса.
Для этого используется объявление static_assert, в котором проверяется аргумент шаблона.

Итак, если, допустим, необходимо, чтобы шаблонный класс принимал в качестве аргумента шаблона только целочисленный тип за исключением типа bool, и чтобы такая проверка была выполнена на этапе компиляции, то можно воспользоваться двумя классами характеристик из библиотеки <type_traits>. Первый класс характеристик будет определять, является ли аргумент шаблона целочисленным, а второй класс характеристик будет проверять, является ли он при этом типом bool, и если является таковым, то компилятор должен выдать сообщение об ошибке.

Вот эти два класса характеристик: std::is_integral и std::is_same.

Тогда условие проверки для шаблонного аргумента в объявлении static_assert может выглядеть следующим образом:


static_assert( std::is_integral<T>::value && !std::is_same<T, bool>::value,  
"An integral type other than bool is required for "
"the template argument of the class" );



Если пользователь класса по ошибке попытается использовать этот класс с типом аргумента шаблона bool, то он получит сообщение об ошибке компилятора, в котором будет присутствовать текст


 цитата:
An integral type other than bool is required for the template argument of the class



Показаннное объявление static_assert полностью решает проблему проверки типа аргумента шаблона по исключению из допустимых значений типа bool.

Однако запись std::is_same<T, bool>::value менее выразительна по сравнению с эквивалентной записью std::is_bool<Tl>::value, при условии, что такая характеристика типа присутствовала бы в стандарте С++. Имя is_bool понятно программистам, даже не знающим языка С++, тем более, что это имя хорошо известно, как я указал в самом начале темы, в языке программирования PHP.

Как сделать так, чтобы использовать это привычное имя вместо записи std::is_same<T, bool>?

Для этого можно объявить шаблонный алиас типа. Выглядеть он может следующим образом:

 template <typename T> 
using is_bool = std::is_same<T, bool>;


Теперь предыдущее объявление static_assert можно переписать в виде:

static_assert( std::is_integral<T>::value && !is_bool<T>::value,  
"An integral type other than bool is required for "
"the template argument of the class" );


Для проверки работоспособности этой конструкции можно использовать простой пример. Правда, при этом не следует использовать компилятор MS VC++ 2010, так как он не поддерживает алиасов типов. Но можно воспользоваться он-лайновым компилятором GCC 4.7.1 по адресу

Вот код примера

 #include <type_traits> 


template <typename T>
using is_bool = std::is_same<T, bool>;

template <typename T>
struct A
{
static_assert( std::is_integral<T>::value && !is_bool<T>::value,
"An integral type other than bool is required for "
"the template argument of the class" );
};


int main()
{
A<int> a1;
A<bool> a2;

return 0;
}


Здесь компилятор должен выдать сообщение об ошибке, включая текст из объявления static_assert, при попытке инстанциировать для объекта a2 класс A с типом аргумента шаблона bool.

Тем не менее этот подход имеет один недостаток. Имя is_bool не является стандартным, а потому не принадлежит стандартному пространству имен std::. А это может путать программистов, которые будут пытатсья поставить перед этим именем вложенное имя std::.

Я сообщил об этом на форуме по обсуждению текущего стандарта в isocpp, предложив данную характеристику типа is_bool включить в стандарт языка С++.

Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 1 [только новые]





ссылка на сообщение  Отправлено: 26.08.12 19:03. Заголовок: Кстати сказать, Dani..


Кстати сказать, Daniel Krügler на форуме по обсуждению стандарта С++ в isocpp предложил подправить конструкцию объявления алиаса шаблонного типа для типа характеристик is_bool

 template <typename T>   
using is_bool = std::is_same<T, bool>;


следующим образом

 template <typename T> 
using is_bool = std::is_same<typename std::remove_cv<T>::type, bool>;


как это имеет место для уже существующего в стандарте типа характеристик std::is_void

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 2
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет