В CppCon 2015, S. Lavavej из Microsoft said, чтобы избежать использования result_of
. Но у меня есть ситуация, когда я не могу найти подходящую альтернативу.Как преобразовать std :: result_of в decltype в аргументе шаблона
Рассмотрите следующий код. Есть ли способ изменить std::result_of<F()>::type
вместо decltype
?
#include <iostream>
#include <future>
#include <type_traits>
template<typename T>
struct NopErrCB
{
constexpr T operator()() const { return T(); }
};
template <typename Func, typename ErrCB>
struct SafeTaskWrapper {
Func f;
ErrCB errCB;
template <typename... T>
auto operator()(T&&... args) -> decltype(f(args...)) {
try
{
return f(std::forward<T>(args)...);
}
catch (...)
{
return errCB();
}
}
};
// vvv OVER HERE vvv
template <typename F>
SafeTaskWrapper<F, NopErrCB<typename std::result_of<F()>::type>> make_safe_task(F&& f) {
return { std::forward<F>(f) };
}
template <typename F, typename ErrCB>
SafeTaskWrapper<F, ErrCB> make_safe_task(F&& f, ErrCB&& cb) {
return { std::forward<F>(f), std::forward<ErrCB>(cb) };
}
int main() {
auto futA = std::async(std::launch::async, make_safe_task([] { throw "A"; return 1; }));
auto futB = std::async(std::launch::async, make_safe_task([] { throw "B"; return 1; }, [] { return 2; }));
auto futC = std::async(std::launch::async, make_safe_task([] { throw "C"; }));
std::cout << futA.get() << std::endl;
std::cout << futB.get() << std::endl;
futC.get();
}
PS. Пожалуйста, не возражайте против цели SafeTaskWrapper. Я знаю, что будущее уже обрабатывает исключения C++. Это всего лишь демоверсия, фактический код предназначен для обработки исключений Windows SEH, но это не имеет значения для этого вопроса.
'decltype (std :: declval()())'? –
Jarod42