Форум » C/C++ » Характеристика типа (type trait)) is_bool в C++ » Ответить

Характеристика типа (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 может выглядеть следующим образом: [pre2]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" );[/pre2] Если пользователь класса по ошибке попытается использовать этот класс с типом аргумента шаблона bool, то он получит сообщение об ошибке компилятора, в котором будет присутствовать текст [quote]An integral type other than bool is required for the template argument of the class[/quote] Показаннное объявление static_assert полностью решает проблему проверки типа аргумента шаблона по исключению из допустимых значений типа bool. Однако запись std::is_same<T, bool>::value менее выразительна по сравнению с эквивалентной записью std::is_bool<Tl>::value, при условии, что такая характеристика типа присутствовала бы в стандарте С++. Имя is_bool понятно программистам, даже не знающим языка С++, тем более, что это имя хорошо известно, как я указал в самом начале темы, в языке программирования PHP. Как сделать так, чтобы использовать это привычное имя вместо записи std::is_same<T, bool>? Для этого можно объявить шаблонный алиас типа. Выглядеть он может следующим образом: [pre2] template <typename T> using is_bool = std::is_same<T, bool>;[/pre2] Теперь предыдущее объявление static_assert можно переписать в виде: [pre2]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" );[/pre2] Для проверки работоспособности этой конструкции можно использовать простой пример. Правда, при этом не следует использовать компилятор MS VC++ 2010, так как он не поддерживает алиасов типов. Но можно воспользоваться он-лайновым компилятором GCC 4.7.1 по адресу Вот код примера [pre2] #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; }[/pre2] Здесь компилятор должен выдать сообщение об ошибке, включая текст из объявления static_assert, при попытке инстанциировать для объекта a2 класс A с типом аргумента шаблона bool. Тем не менее этот подход имеет один недостаток. Имя is_bool не является стандартным, а потому не принадлежит стандартному пространству имен std::. А это может путать программистов, которые будут пытатсья поставить перед этим именем вложенное имя std::. Я сообщил об этом на форуме по обсуждению текущего стандарта в isocpp, предложив данную характеристику типа is_bool включить в стандарт языка С++.

Ответов - 1

Сыроежка: Кстати сказать, Daniel Krügler на форуме по обсуждению стандарта С++ в isocpp предложил подправить конструкцию объявления алиаса шаблонного типа для типа характеристик is_bool [pre2] template <typename T> using is_bool = std::is_same<T, bool>; [/pre2] следующим образом [pre2] template <typename T> using is_bool = std::is_same<typename std::remove_cv<T>::type, bool>;[/pre2] как это имеет место для уже существующего в стандарте типа характеристик std::is_void



полная версия страницы