. CallbackType CallbackImpl:
enum CallbackType
{
SYNC,
ASYNC,
};
template<CallbackType CB, typename... Args>
class CallbackImpl
{
};
, " ":
template <CallbackType cb>
using CallbackT = std::integral_constant<CallbackType, cb>;
template <typename T>
struct is_callback_type
: std::false_type
{};
template <CallbackType cb>
struct is_callback_type<CallbackT<cb>>
: std::true_type
{};
template <typename T>
using is_callback_type_t = typename is_callback_type<T>::type;
template <typename AlwaysVoid, typename... Args>
struct construct_callback_impl
{
using type = CallbackImpl<SYNC, Args...>;
};
template <typename CallbackType, typename... Args>
struct construct_callback_impl<
// Use this specialization only if the first type is our CallbackT
typename std::enable_if<is_callback_type_t<CallbackType>::value>::type,
CallbackType,
Args...>
{
using type = CallbackImpl<CallbackType::value, Args...>;
};
template <typename... Args>
using Callback = typename construct_callback_impl<void, Args...>::type;
:
Callback<int, int> // type is CallbackImpl<SYNC, int, int>
Callback<CallbackT<SYNC>, int, int> // type is CallbackImpl<SYNC, int, int>
Callback<CallbackT<ASYNC>, int, int> // type is CallbackImpl<ASYNC, int, int>
Callback<> // type is CallbackImpl<SYNC>
Live on Godbolt
, , .