Obj-C++: template metafunction for recognizing Objective-C classes?

You can read my most recent rant about ObjC++ in this question. Avoid it as much as you can possibly get away with. Definitely don't try to integrate Objective-C into C++ template metaprogramming. The compiler might actually rip a hole in space.

Hyperbole aside, what you're trying to do is likely impossible. Objective-C classes are just structs. (C++ classes actually just structs too.) There's not much compile-time introspection available.

An id is a C pointer to a struct objc_object. At runtime, every object is an id, no matter its class.

typedef struct objc_class *Class;
typedef struct objc_object {
    Class isa;
} *id;

Here is a simplistic solution that should work in most (if not all? Can anyone think of when this might fail?) cases (it uses clang 3.0 via xcode 4.2 - use typedefs instead of using aliases for earlier clang versions):

template<class T> struct IsObjectiveCClass 
  using yesT = char (&)[10];
  using noT = char (&)[1];
  static yesT choose(id);
  static noT choose(...);
  static T make();
  enum { value = sizeof(choose(make())) == sizeof(yesT) }; 


As with the accepted answer, you can test whether the type is convertible to id, in C++17:

template <typename T>
struct is_objc_ptr : std::integral_constant<bool, 
  std::is_convertible_v<T, id> && !std::is_null_pointer_v<T>> {};
template <typename T>
constexpr bool is_objc_ptr_v = is_objc_ptr<T>::value;


static_assert(!is_objc_ptr_v<char *>);
static_assert(is_objc_ptr_v<NSObject *>);

I don't know of a way to discover ObjC inheritance relationships at compile-time; in theory they're changeable at runtime so you would have to query the runtime.