Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
stdex расположена в «C:\my_code\stdex\», путь до type_traits будет «C:\my_code\stdex\type_traits». Тогда в компиляторе:
include path = «C:\my_code\stdex\»
#include <type_traits> // OK
include path = «C:\my_code\»
#include <stdex/type_traits> // compilation error "can not include 'stdex/type_traits.h': no such file or directory" #include <stdex/type_traits.hpp> // приходится использовать так
#include <iostream>
struct true_type
{
enum {value = 1};
};
struct false_type
{
enum {value = 0};
};
template<typename T>
struct is_integer_impl : false_type {};
#define DECLARE_INTEGER(T) \
template<> \
struct is_integer_impl<T> : true_type {}
DECLARE_INTEGER(char);
DECLARE_INTEGER(unsigned char);
DECLARE_INTEGER(signed char);
DECLARE_INTEGER(unsigned short);
DECLARE_INTEGER(signed short);
DECLARE_INTEGER(unsigned int);
DECLARE_INTEGER(signed int);
DECLARE_INTEGER(unsigned long);
DECLARE_INTEGER(signed long);
template<typename T>
struct is_integer : is_integer_impl<T> {};
template<typename T>
struct is_class
{
typedef char yes;
typedef int no;
template<class U>
static yes doCheck(void (U::*)());
template<class U>
static no doCheck(...);
enum {value = (sizeof(doCheck<T>(0)) == sizeof(yes))};
};
template<typename T>
struct is_enum
{
enum {value = !is_integer<T>::value && !is_class<T>::value};
};
enum TestEnum
{
Item1,
Item2
};
struct TestStruct
{
};
int main()
{
std::cout << is_integer<int>::value << std::endl;
std::cout << is_enum<int>::value << std::endl;
std::cout << is_class<int>::value << std::endl;
std::cout << std::endl;
std::cout << is_integer<TestStruct>::value << std::endl;
std::cout << is_enum<TestStruct>::value << std::endl;
std::cout << is_class<TestStruct>::value << std::endl;
std::cout << std::endl;
std::cout << is_integer<TestEnum>::value << std::endl;
std::cout << is_enum<TestEnum>::value << std::endl;
std::cout << is_class<TestEnum>::value << std::endl;
return 0;
}is_class<EnumType>::value будет true на некоторых компиляторах, т.к. по сути им без разницы что за контейнер. Если он не встроенный тип, то он по умолчанию считается имеющим member pointer. … проблема возникает с неполным типом T[] (массив без указания длины). Дело в том что данный тип не определяется некоторыми компиляторами (C++ Builder) при специализации шаблона, и универсальное решение здесь я пока что не нашел.
namespace detail {
template <typename T>
static yes_type foo(T (*)[]);
static no_type foo(...);
template <typename T>
static T * declptr();
}
// is_array
template <class Tp>
struct is_array
{
enum
{
value = sizeof(detail::foo(detail::declptr<Tp>())) == sizeof(yes_type)
};
};
template <class Tp, std::size_t Size>
struct is_array<Tp[Size]>
: true_type
{ };int accumulate(int n, const int (*array)[])The committees decided that functions such as this, that accept a pointer or reference to an array with unknown bound, complicate declaration matching and overload resolution rules in C++. The committees agreed that, since such functions have little utility and are fairly uncommon, it would be simplest to just ban them. Hence, the C++ draft now states:
If the type of a parameter includes a type of the form pointer to array of unknown bound of T or reference to array of unknown bound of T, the program is ill-formed.
Как я стандартную библиотеку C++11 писал или почему boost такой страшный. Глава 4.3