invoke
在for_each2节中讲到for_each的调用函数invoke,在第for_each3节中,分析了一个关键宏CPP_auto_fun的实现,发现原来的代码中,Eric的例子返回值应该需要auto,给他提了patch. 这节回到invoke的分析。
operator ()
template<class F, class T, class T1, class... Args>
constexpr auto CPP_auto_fun(operator())(F T::*f, T1&& t1, Args&&... args)(const)
(
return (invoke_fn::coerce<T>(static_cast<T1&&>(t1), 0).*f)
(static_cast<Args&&>(args)...)
)
经过CPP_auto_fun的扩展
template<class F, class T, class T1, class... Args>
constexpr auto operator() (F T::*f, T1&& t1, Args&&... args)
const noexcept(noexcept(decltype((invoke_fn::coerce<T>(static_cast<T1&&>(t1), 0).*f) (static_cast<Args&&>(args)...))((invoke_fn::coerce<T>(static_cast<T1&&>(t1), 0).*f) (static_cast<Args&&>(args)...))))
-> decltype((invoke_fn::coerce<T>(static_cast<T1&&>(t1), 0).*f) (static_cast<Args&&>(args)...))
{
· return ((invoke_fn::coerce<T>(static_cast<T1&&>(t1), 0).*f) (static_cast<Args&&>(args)...));
}
这个的关键是coerce的作用; 要分析coerce 先要分析两个宏定义:
CPP_ret
#if CPP_CXX_CONCEPTS
#define CPP_ret(...) \
__VA_ARGS__ CPP_PP_EXPAND \
/**/
#else
#define CPP_ret \
CPP_broken_friend_ret