, result_of . , result_of, . decltype.
-, , result_of .
struct evil {
template<class...Args>
int operator()(Args&&)&&{return 0;}
template<class...Args>
std::string operator()(Args&&)const&{return "hello";}
};
evil{} , . , f SafeTaskWrapper lvalue, result_of rvalue.
, S.T.L. .
std::result_of_t<F(Args...)> 1 decltype( std::declval<F>()( std::declval<Args>()... ) ), decltype( std::declval<F>()()). result_of_t decltype .
, .
struct anything_really {
template<class T> operator T() const { return {}; }
};
struct return_anything {
anything_really operator()() const { return {}; }
};
errCB. , .
, " ". :
template<class R>
struct smart_invoke {
template<class F>
R operator()(F&& f)const {
return std::forward<F>(f)();
}
};
template<>
struct smart_invoke<void> {
template<class F>
void operator()(F&& f)const {
std::forward<F>(f)();
}
};
:
template <typename Func, typename ErrCB=return_anything>
struct SafeTaskWrapper {
Func f;
ErrCB errCB;
template <class... Ts>
decltype(auto) operator()(Ts&&... args) {
try {
return f(std::forward<T>(args)...);
} catch (...) {
using R=decltype( f( std::forward<T>(args)... ) );
return smart_invoke<R>{}(errCB);
}
}
};
factory. , .
template <class ErrCB=return_anything, class F>
SafeTaskWrapper<F, ErrCB> make_safe_task(F&& f, ErrCB&& cb = {}) {
return { std::forward<F>(f), std::forward<ErrCB>(cb) };
}
, errCB , .
result_of_t .
trailing return decltype . , (key), .
1 , f - .., . ++ 17 std::invoke operator() decltype. , , .