Ещё один удобный способ выбора реализации
От: Шахтер Интернет  
Дата: 18.05.15 09:25
Оценка:

/* enum NothingType */

enum NothingType { Nothing };

/* type IsVoid<T> */

template <class T>
struct DoIsVoid
 {
 };

template <>
struct DoIsVoid<void>
 {
  using Ret = void ;
 };

template <class T>
using IsVoid = typename DoIsVoid<T>::Ret ;

/* Action() */

template <class T>
void DoAction(T &,int,int)
 {
  Printf(Con,"default\n");
 }

template <class T>
auto DoAction(T &obj,NothingType,int) -> IsVoid< decltype( obj.method2() ) >
 {
  Printf(Con,"method2\n");

  obj.method2();
 }

template <class T>
auto DoAction(T &obj,NothingType,NothingType) -> IsVoid< decltype( obj.method1() ) >
 {
  Printf(Con,"method1\n");

  obj.method1();
 }

template <class T>
void Action(T &obj)
 {
  DoAction(obj,Nothing,Nothing);
 }

/* struct Test */

struct Test
 {
 };

/* struct Test1 */

struct Test1
 {
  void method1() {}
 };

/* struct Test2 */

struct Test2
 {
  void method2() {}
 };

/* struct Test12 */

struct Test12
 {
  void method1() {}

  void method2() {}
 };

/* main() */

int main()
 {
  Test test;
  Test1 test1;
  Test2 test2;
  Test12 test12;

  Action(test); // default
  Action(test1); // method1
  Action(test2); // method2
  Action(test12); // method1

  return 0;
 }
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.