आपने एक सिंटैक्स बहुत metaprogramming का एक सा के साथ अपने मूल वाक्य रचना के करीब हो सकता है। आप को परिभाषित है कि आपके द्वारा CallbackType
और एक CallbackImpl
:
enum CallbackType
{
SYNC,
ASYNC,
};
template<CallbackType CB, typename... Args>
class CallbackImpl
{
};
तो कुछ बातें "डिफ़ॉल्ट तर्क" पाने के लिए क्या: फिर
// We need to treat the CallbackType argument as a type, not as a value.
// Thus, we need to wrap it in a type.
template <CallbackType cb>
using CallbackT = std::integral_constant<CallbackType, cb>;
// We need to be able to detect if the first type passed in is this CallbackT
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;
// Here we do the work. This is the base case, where the first arg
// is not a CallbackT. Note that this works for an empty Args as well
template <typename AlwaysVoid, typename... Args>
struct construct_callback_impl
{
using type = CallbackImpl<SYNC, Args...>;
};
// If the Args list is of at least size 1,
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...>
{
// Forward the specified CallbackType on to the CallbackImpl
using type = CallbackImpl<CallbackType::value, Args...>;
};
// Wrap this utility into a nicer calling syntax
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
मुझे लगता है कि यह स्पष्ट है कि यह आमतौर पर क्यों नहीं किया जाता है।
बहुत बुरा हम अच्छी चीजें नहीं कर सकते :(, मैं हमेशा कॉलमटाइप को enum टेम्पलेट तर्क के रूप में लेना चाहता हूं और बाकी को विविधता के रूप में लेना चाहता हूं, लेकिन मुझे लगता है कि यह चीजों को अलग नहीं बताता है। –