2011-12-27 22 views
8

मैं अब इस कोड का उपयोग कर रहा: (। उपयोगकर्ता तर्कों के किसी भी संख्या के साथ एक समारोह के साथ argc फोन नहीं कर सकते हैं)हो रही तर्क गणना

size_t argc(std::function<Foo()>) 
    { return 0; } 

    size_t argc(std::function<Foo(Bar)>) 
    { return 1; } 

    size_t argc(std::function<Foo(Bar, Bar)>) 
    { return 2; } 

    size_t argc(std::function<Foo(Bar, Bar, Bar)>) 
    { return 3; } 

    // ... 

लेकिन यह थोड़े बदसूरत और सीमित है इसे करने का कोई बेहतर तरीका है?

नोट: रिटर्न प्रकार और तर्क प्रकार हमेशा समान होते हैं। मुझे पता है कि मैं किसी भी प्रकार को स्वीकार करने के लिए टेम्पलेट का उपयोग कर सकता हूं, लेकिन मुझे इसकी आवश्यकता नहीं है।

+0

तर्क प्रकार UMH हमेशा एक ही नहीं है ... –

+1

@ JohannesSchaub-litb मुझे लगता है कि इसका मतलब है कि वे हमेशा के रूप में ही कर रहे हैं उन उदाहरण: वापसी मूल्य के लिए 'Foo', और सभी तर्कों के लिए' बार '। –

उत्तर

12

क्लीनर संस्करण, प्रयोग करने योग्य वास्तविक वस्तुओं के साथ:

template<class R, class... Args> 
constexpr unsigned arity(std::function<R(Args...)> const&){ 
    return sizeof...(Args); 
} 
5

निम्नलिखित किसी भी arity के लिए काम करेंगे, लेकिन स्वीकार मनमाना तर्क प्रकार:

template <typename T> 
struct arity 
{ 
}; 

template <typename... Args> 
struct arity<std::function<Foo(Args...)>> 
{ 
    static const int value = sizeof...(Args); 
}; 

तुम सच प्रकार Foo(Bar, Bar, ...) के कार्यों होने के लिए अपने तर्क प्रकार सीमित करना चाहते हैं, तो आप कुछ इस तरह कर सकते हैं:

template <typename T> 
struct arity 
{ 
}; 

template <typename... Args> 
struct const_tuple 
{ 
}; 

template <> 
struct const_tuple<> 
{ 
    struct unsupported_function_type { }; 
}; 

template <typename... Args> 
struct const_tuple<Bar, Args...> 
{ 
    typedef typename const_tuple<Args...>::unsupported_function_type unsupported_function_type; 
}; 

template <typename... Args> 
struct arity<std::function<Foo(Args...)>> : public const_tuple<Args...>::unsupported_function_type 
{ 
    static const int value = sizeof...(Args); 
}; 

जब भी किसी असमर्थित फ़ंक्शन प्रकार के साथ धैर्य को बुलाया जाता है तो यह आपको संकलित त्रुटि देगा। @ पाओलो के जवाब की