Я хочу сделать что-то вроде этого:
Я хотел бы иметь шаблонный класс, похожий на буст, «необязательный», т. Е. Он должен содержать тип, а также то, является ли значение допустимым или нет.
Допустим, у нас есть класс А с методами
A::X(int value) -> int
A::Y(int value) -> int
Давайте назовем мой шаблон MyOptional
Я также хотел бы «прервать» вызовы функций, если значение недопустимо. Я полагаю, что тип возвращаемого значения всех вызовов функций должен быть
MyOptional< T>, так, например, делаем:
MyOptional<A> a;
a->X(3);
должен дать мне дополнительный без действительного значения.
Это означает, что мне нужны две функциональные возможности, не включенные в дополнительные опции:
Это вообще возможно в C ++? Я смотрел на -> перегрузку, но это, кажется, определяет, с каким объектом выполняется вызов функции, не позволяя мне изменить возвращаемое значение.
Есть решение с использованием 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_type
— typedef
для его типа аргумента.
Пример использования:
MyOptional<int> result = CALL(ma, X, 3);
Других решений пока нет …