Ещё один удобный способ выбора реализации
От: Шахтер Интернет  
Дата: 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. Парадоксы
Re: Ещё один удобный способ выбора реализации
От: jazzer Россия Skype: enerjazzer
Дата: 18.05.15 09:54
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>template <class T>
Ш>auto DoAction(T &obj,NothingType,int) -> IsVoid< decltype( obj.method2() ) >

Ш>template <class T>
Ш>auto DoAction(T &obj,NothingType,NothingType) -> IsVoid< decltype( obj.method1() ) >


IsVoid не нужен:

template <class T, class = decltype( std::declval<T&>().method2())>
void DoAction(T &obj,NothingType,int)

template <class T, class = decltype( std::declval<T&>().method1())>
void DoAction(T &obj,NothingType,NothingType)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Ещё один удобный способ выбора реализации
От: uzhas Ниоткуда  
Дата: 18.05.15 09:54
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>

/* type IsVoid<T> */

template <class T>
struct DoIsVoid
 {
 };

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

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


можно упростить до
template <class T>
using IsVoid = typename std::is_same<void, T>::type;

тут же весь замысел в другой части кода
Re[2]: Ещё один удобный способ выбора реализации
От: uzhas Ниоткуда  
Дата: 18.05.15 09:57
Оценка:
Здравствуйте, jazzer, Вы писали:

J>IsVoid не нужен:

он валидирует тип возвращаемого значения метода
Re[3]: Ещё один удобный способ выбора реализации
От: jazzer Россия Skype: enerjazzer
Дата: 18.05.15 10:03
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, jazzer, Вы писали:


J>>IsVoid не нужен:

U>он валидирует тип возвращаемого значения метода

Имхо, суть его кода в том, чтоб выбрать реализацию, исходя из наличия/отсутствия метода в классе. Мог быть неправ, конечно же, послушаем начальника транспортного цеха автора.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[4]: Ещё один удобный способ выбора реализации
От: Шахтер Интернет  
Дата: 18.05.15 13:41
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, uzhas, Вы писали:


U>>Здравствуйте, jazzer, Вы писали:


J>>>IsVoid не нужен:

U>>он валидирует тип возвращаемого значения метода

J>Имхо, суть его кода в том, чтоб выбрать реализацию, исходя из наличия/отсутствия метода в классе. Мог быть неправ, конечно же, послушаем начальника транспортного цеха автора.


Зависит от того, что тебе надо. Если нужно валидировать тип возвращаемого значения, то добавляешь IsVoid. Если не нужно -- не добавляешь.
Короче -- вишенка на торте.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Отредактировано 18.05.2015 13:49 Шахтер . Предыдущая версия .
Re[2]: Ещё один удобный способ выбора реализации
От: Шахтер Интернет  
Дата: 18.05.15 14:01
Оценка: +1
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, Шахтер, Вы писали:


Ш>>

U>
U>/* type IsVoid<T> */

U>template <class T>
U>struct DoIsVoid
U> {
U> };

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

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


U>можно упростить до

U>
U>template <class T>
U>using IsVoid = typename std::is_same<void, T>::type;
U>


Я хочу, чтобы тип возвращаемого значение был void, а не std::true_type.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[3]: Ещё один удобный способ выбора реализации
От: uzhas Ниоткуда  
Дата: 18.05.15 14:56
Оценка: -1
Здравствуйте, Шахтер, Вы писали:

Ш>Я хочу, чтобы тип возвращаемого значение был void, а не std::true_type.

ой, я тоже так хотел
Re[3]: Ещё один удобный способ выбора реализации
От: sokel Россия  
Дата: 18.05.15 14:59
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>Я хочу, чтобы тип возвращаемого значение был void, а не std::true_type.


template <class T>
using void_or_die = typename std::enable_if<std::is_same<void, T>::value, void>::type;
Re: Ещё один удобный способ выбора реализации
От: sokel Россия  
Дата: 18.05.15 15:57
Оценка:
Здравствуйте, Шахтер, Вы писали:

Может когда нибудь все компиляторы согласятся с Уолтером Брауном, тогда наверное и как нибудь через его void_t можно будет...
Re[2]: Ещё один удобный способ выбора реализации
От: sokel Россия  
Дата: 18.05.15 18:44
Оценка:
Здравствуйте, sokel, Вы писали:

S>Здравствуйте, Шахтер, Вы писали:


S>Может когда нибудь все компиляторы согласятся с Уолтером Брауном, тогда наверное и как нибудь через его void_t можно будет...


Чтобы точно method ещё declval забыл...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.