Ещё один удобный способ выбора реализации
От:
Шахтер
Дата: 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)
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>он валидирует тип возвращаемого значения метода
Имхо, суть его кода в том, чтоб выбрать реализацию, исходя из наличия/отсутствия метода в классе. Мог быть неправ, конечно же, послушаем начальника транспортного цеха автора.
Re[4]: Ещё один удобный способ выбора реализации
От:
Шахтер
Дата: 18.05.15 13:41
Оценка:
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, uzhas, Вы писали:
U>>Здравствуйте, jazzer, Вы писали:
J>>>IsVoid не нужен:
U>>он валидирует тип возвращаемого значения метода
J>Имхо, суть его кода в том, чтоб выбрать реализацию, исходя из наличия/отсутствия метода в классе. Мог быть неправ, конечно же, послушаем начальника транспортного цеха автора.
Зависит от того, что тебе надо. Если нужно валидировать тип возвращаемого значения, то добавляешь IsVoid. Если не нужно -- не добавляешь.
Короче -- вишенка на торте.
В XXI век с
CCore .
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
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 забыл ...
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить