C++代码
/** When this Future has completed, execute func which is a function that
takes one of:
(const) Try<T>&&
(const) Try<T>&
(const) Try<T>
(const) T&&
(const) T&
(const) T
(void)
Func shall return either another Future or a value.
A Future for the return type of func is returned.
Future<string> f2 = f1.then([](Try<T>&&) { return string("foo"); });
The Future given to the functor is ready, and the functor may call
value(), which may rethrow if this has captured an exception. If func
throws, the exception will be captured in the Future that is returned.
*/
template <
typename F,
typename FF = typename detail::FunctionReferenceToPointer<F>::type,
typename R = detail::callableResult<T, FF>>
typename R::Return then(F&& func) {
typedef typename R::Arg Arguments;
return thenImplementation<FF, R>(std::forward<FF>(func), Arguments());
}
template<typename F, typename... Args>
struct callableWith {
template<typename T,
typename = detail::resultOf<T, Args...>>
static constexpr std::true_type
check(std::nullptr_t) { return std::true_type{}; };
template<typename>
static constexpr std::false_type
check(...) { return std::false_type{}; };
typedef decltype(check<F>(nullptr)) type;
static constexpr bool value = type::value;
};
template<typename T, typename F>
struct callableResult {
typedef typename std::conditional<
callableWith<F>::value,
detail::argResult<false, F>,
typename std::conditional<
callableWith<F, T&&>::value,
detail::argResult<false, F, T&&>,
typename std::conditional<
callableWith<F, T&>::value,
detail::argResult<false, F, T&>,
typename std::conditional<
callableWith<F, Try<T>&&>::value,
detail::argResult<true, F, Try<T>&&>,
detail::argResult<true, F, Try<T>&>>::type>::type>::type>::type Arg;
typedef isFuture<typename Arg::Result> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
};
template<typename F, typename... Args>
using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
这里一大波template我们一个一个来。FunctionReferenceToPointer可以无视掉,你可以想象成FF就是Fstd::declval 让你把 F变成 F&&,所以可以用template<typename F, typename... Args>
using resultOf = decltype(std::declval<F>()(std::declval<Args>()...));
这样的语法拿到F(Args args...) 的返回值,不管F是object还是lambda。这样,resultOf可以拿到我们的callback的返回type。现在我们得把这个返回值跟下一个函数的argument对应起来。这里我们用callableWithtemplate<typename F, typename... Args>
struct callableWith {
template<typename T,
typename = detail::resultOf<T, Args...>>
static constexpr std::true_type
check(std::nullptr_t) { return std::true_type{}; };
template<typename>
static constexpr std::false_type
check(...) { return std::false_type{}; };
typedef decltype(check<F>(nullptr)) type;
static constexpr bool value = type::value;
};
这里check有两个specialization,一个在编译时候会返回true一个会返回false。注意只要不符合第一个specialization的都是false,也就是说resultOf没有成功,check(nullptr) 就是false type。这个技巧叫做Substitution Failure Is Not An Error SFINAE - cppreference.com 。再配倒数第二行的typedef,如果 F可以接受args,那么callableWith<F>(Args args...)::value == true type。最后,把所有我们允许的类用std::conditional一个一个试过去template<typename T, typename F>
struct callableResult {
typedef typename std::conditional<
callableWith<F>::value,
detail::argResult<false, F>,
typename std::conditional<
callableWith<F, T&&>::value,
detail::argResult<false, F, T&&>,
typename std::conditional<
callableWith<F, T&>::value,
detail::argResult<false, F, T&>,
typename std::conditional<
callableWith<F, Try<T>&&>::value,
detail::argResult<true, F, Try<T>&&>,
detail::argResult<true, F, Try<T>&>>::type>::type>::type>::type Arg;
typedef isFuture<typename Arg::Result> ReturnsFuture;
typedef Future<typename ReturnsFuture::Inner> Return;
};
版权所有:江苏和讯自动化设备有限公司所有 备案号:苏ICP备2022010314号-1
技术支持: 易动力网络