Как проверить, что тип шаблона шаблона является неотъемлемым?

В описании некоторой функции std-шаблона я увидел что-то вроде:

если параметр шаблона имеет интегральный тип, поведение такое-то и такое. в противном случае он такой-то.

Как я могу сделать аналогичный тест? Возможно, dynamic_cast?

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

4 ответа

В дополнение к другим ответам следует отметить, что тест можно использовать во время выполнения, но также и во время компиляции, чтобы выбрать правильную реализацию в зависимости от того, является ли тип интегральным или нет:

Версия выполнения:

// Include either <boost type_traits="" is_integral.hpp=""> (if using Boost) 
// or <type_traits> (if using c++1x)
// In the following, is_integral shoudl be prefixed by either boost:: or std::
template <typename t="">
void algorithm(const T & t)
{
 // some code
 if (is_integral<t>::value)
 {
 // operations to perform if T is an integral type
 }
 else
 {
 // operations to perform if T is not an integral type
 }
 // some other code
}
</t></typename></type_traits></boost>

Однако это решение может быть улучшено, когда реализация алгоритма сильно зависит от теста. В этом случае у нас будет тест в верхней части функции, затем большой блок then и большой блок else. В этом случае общий подход заключается в том, чтобы перегрузить функцию и заставить компилятор выбрать правильную реализацию с использованием SFINAE. Легкий способ сделать это - использовать boost::enable_if:

#include <boost utility="" enable_if.hpp="">
#include <boost type_traits="" is_integral.hpp="">
template <typename t="">
typename boost::enable_if<boost::is_integral<t> >::type
algorithm(const T & t)
{
 // implementation for integral types
}
template <typename t="">
typename boost::disable_if<boost::is_integral<t> >::type
algorithm(const T & t)
{
 // implementation for non integral types
}
</boost::is_integral<t></typename></boost::is_integral<t></typename></boost></boost>

При вызове функции algorithm компилятор "выберет" правильную реализацию в зависимости от того, является ли параметр шаблона интегральным или нет.


Одна возможность:

#include <type_traits> 
#include <iostream> 
struct trivial 
{ 
 int val; 
}; 
int main() 
{ 
 std::cout << "is_integral<trivial> == " << std::boolalpha 
 << std::is_integral<trivial>::value << std::endl; 
 std::cout << "is_integral<int> == " << std::boolalpha 
 << std::is_integral<int>::value << std::endl; 
 std::cout << "is_integral<float> == " << std::boolalpha 
 << std::is_integral<float>::value << std::endl; 
 return (0); 
} 
</float></float></int></int></trivial></trivial></iostream></type_traits>

Итак, вы затем используете std::is_integral<> для определения действия.


Если вы не можете использовать возможности С++ 11, std::numeric_limits<t>::is_integer</t> делает то же самое как std::is_integral<t>::value</t>, и доступно с С++ 98.

Обратите внимание, что версия 98 - это inte ger, а не inte gral.


Boost.TypeTraits предоставляет is_integral <> (), как описано в другом ответе, если ваш компилятор еще не поддерживает функции С++ для следующий стандарт.

licensed under cc by-sa 3.0 with attribution.