Selección entre tipos válidos y no válidos

Si tenemos una metafunción de plantilla como std::conditional , podemos “seleccionar” tipos basados ​​en una condición de tiempo de comstackción booleana. Por ejemplo:

 template  struct conditional; template  struct conditional  { using type = T; }; template  struct conditional  { using type = U; }; const bool whats_big = sizeof( int ) > sizeof( double ); using bigger_type = typename conditional::type; 

Mi pregunta es: ¿hay alguna forma de seleccionar entre un tipo válido y un tipo no válido?

Actualmente estoy implementando una clase de evento. Los eventos tienen un parámetro de remitente y un número variable de eventos args:

 template class event; 

Por lo tanto, las funciones con tipo void(SENDER& , ARGS&...) podrían usarse como controladores de eventos. En ese caso, se llama a los manejadores pasando una referencia al objeto que ha generado el evento (Threas the sender param).
Por otro lado, quiero una manera de permitir que las funciones de miembro remitente sean manejadores de eventos, en otras palabras, funciones de tipo void(SENDER::*)(ARGS&...) .

El problema es que no puedo usar una oración como:

  using handler_type = typename conditional<std::is_class::value,void(SENDER::*)(ARGS&...) , void(SENDER& , ARGS&...)>::type; 

Debido a que en el caso de que SENDER no sea un tipo de clase, el primer tipo no es válido (utiliza un puntero a un miembro de un tipo que no es de clase).

Puedes hacerlo con un nivel extra de direccionamiento indirecto:

 template  struct sender_chooser { using type = void(*)(T &, Args &...); }; template  struct sender_chooser { using type = void (T::*)(Args &...); }; template  struct sender_type { using type = typename sender_chooser::value, T, Args...>::type; }; 

Uso:

 sender_type::type 

Esto es void (MySender::*)(Arg1 &, Arg2 &, Arg3 &) si MySender es un tipo de clase, o de lo contrario void (*)(Sender &, Arg1 &, Arg2 &, Arg3 &) .

(También es posible que desee permitir los sindicatos.)