template <typename T>
struct is_pointer_type
{
enum { value = false };
};
template <typename T>
struct is_pointer_type<T*>
{
enum { value = true };
};
template <typename T>
bool is_pointer(const T&)
{
return is_pointer_type<T>::value;
}
Johannes zauważył:
To jest rzeczywiście brakuje specjalizacje dla const T * T * T * lotny i const lotny myślę.
Rozwiązanie:
template <typename T>
struct remove_const
{
typedef T type;
};
template <typename T>
struct remove_const<const T>
{
typedef T type;
};
template <typename T>
struct remove_volatile
{
typedef T type;
};
template <typename T>
struct remove_volatile<volatile T>
{
typedef T type;
};
template <typename T>
struct remove_cv : remove_const<typename remove_volatile<T>::type> {};
template <typename T>
struct is_unqualified_pointer
{
enum { value = false };
};
template <typename T>
struct is_unqualified_pointer<T*>
{
enum { value = true };
};
template <typename T>
struct is_pointer_type : is_unqualified_pointer<typename remove_cv<T>::type> {};
template <typename T>
bool is_pointer(const T&)
{
return is_pointer_type<T>::value;
}
... ale oczywiście to jest po prostu wymyślania koła std::type_traits
, bardziej lub mniej :)
Czy jest jakiś powód, aby używać tego rozwiązania zamiast tego, które podaje Thomas? – Job
@Job Działa dla typów niekodowanych :) – fredoverflow
Tak, oczywiście :) Miałem na myśli odpowiedź Thomasa, ale jako "const T &" jako parametr. – Job