Использование шаблона для изменения поведения вызовов функций в зависимости от состояния в Stack Overflow

Я хочу сделать что-то вроде этого:

Я хотел бы иметь шаблонный класс, похожий на буст, «необязательный», т. Е. Он должен содержать тип, а также то, является ли значение допустимым или нет.

Допустим, у нас есть класс А с методами

A::X(int value) -> int
A::Y(int value) -> int

Давайте назовем мой шаблон MyOptional

Я также хотел бы «прервать» вызовы функций, если значение недопустимо. Я полагаю, что тип возвращаемого значения всех вызовов функций должен быть
MyOptional< T>, так, например, делаем:

MyOptional<A> a;
a->X(3);

должен дать мне дополнительный без действительного значения.

Это означает, что мне нужны две функциональные возможности, не включенные в дополнительные опции:

  • Условный вызов функции или шаблон определяется поведением в зависимости от состояния.
  • Встраивание возвращаемого типа в тип шаблона.

Это вообще возможно в C ++? Я смотрел на -> перегрузку, но это, кажется, определяет, с каким объектом выполняется вызов функции, не позволяя мне изменить возвращаемое значение.

1

Решение

Есть решение с использованием C ++ 11. предполагать MyOptional шаблон имеет такую ​​же функциональность как boost::optional один (такой как operator*, operator->, преобразование в bool оператор и т. д.). Тогда мы можем написать шаблон функции Call:

template <class Class, typename Method, typename... Arguments>
auto Call2
(
MyOptional<Class>& optional,
Method Class::*method,
Arguments&&... arguments
)
-> MyOptional
<decltype((*optional.*method)(std::forward<Arguments>(arguments)...))>
{
typedef decltype((*optional.*method)(std::forward<Arguments>(arguments)...))
ResultType;

if (optional)
{
return MyOptional<ResultType>
((*optional.*method)(std::forward<Arguments>(arguments)...));
// you can add here some code for processing the value returned by method
}
else
{
return MyOptional<ResultType>();
}
}

Пример этой функции с использованием:

MyOptional<A> a;

MyOptional<int> result = Call(a, &A::X, 3);

Я не мог найти способ опустить &A:: префикс к имени метода только с языковыми инструментами. Но есть способ использования макроса variadic:

#define CALL(optional, method, ...) \
Call(optional, &decltype(optional)::value_type::method, ##__VA_ARGS__)

Здесь предполагается, что MyOptional шаблон определяет value_typetypedef для его типа аргумента.

Пример использования:

MyOptional<int> result = CALL(ma, X, 3);
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]