2011-06-01 11 views
7

मैं रिटर्न प्रकार और पैरामीटर प्रकारों के नलिका और यूनरी फ़ंक्शन पॉइंटर्स, std :: फ़ंक्शन ऑब्जेक्ट्स, और फ़ैक्टर (लैम्ब्स समेत) का पता कैसे लगा सकता हूं?फ़ंक्शन ऑब्जेक्ट (फ़ैक्टर) और लैम्ब्डा लक्षणों का पता लगाना

बूस्ट का function_traits और functional traits मुझे बॉक्स से बाहर नहीं ले जाता है, लेकिन मैं उन्हें पूरक या बदलने के लिए खुला हूं।

मैं कुछ इस तरह कर सकता है:

namespace nsDetail 
{ 
    class Dummy { Dummy(); }; 
} 

template<class Fn> struct FnTraits; 

template<class R> 
struct FnTraits<R(*)()> 
{ 
    typedef nsDetail::Dummy ParamType; 
    typedef R    ReturnType; 
    typedef R Signature(); 
}; 

template<class R, class P> 
struct FnTraits<R(*)(P)> 
{ 
    typedef P ParamType; 
    typedef R ReturnType; 
    typedef R Signature(P); 
}; 

template<class R> 
struct FnTraits< std::function<R()> > 
{ 
    typedef nsDetail::Dummy ParamType; 
    typedef R    ReturnType; 
    typedef R Signature(); 
}; 

template<class R, class P> 
struct FnTraits< std::function<R(P)> > 
{ 
    typedef P ParamType; 
    typedef R ReturnType; 
    typedef R Signature(P); 
}; 

लेकिन मैं के लिए functors/lambdas कैसे विशेषज्ञ होना चाहिए?

अद्यतन: शायद this answer to a different question में कुछ ऐसा है, लेकिन अधिभार से विशेषज्ञता के लिए अनुवाद किया गया है?

उत्तर

6

यह functors के लिए सामान्य स्थिति है, यानी वर्ग प्रकार operator() का उपयोग करने में संभव नहीं है। इसमें लैम्ब्डा ऑब्जेक्ट्स भी शामिल हैं।

struct functor { 
    double 
    operator()(double) const; 

    int 
    operator()(int) const; 
}; 

typedef function_traits<functor>::result_type result_type; 

क्या result_type होना चाहिए: एक मामले में जहां operator() ओवरलोड हो गया है पर विचार करें?

ध्यान दें कि, एक समाधान के रूप में, कुछ प्रोटोकॉल (जैसे boost::apply_visitor Boost.Variant से) की आवश्यकता है कि एक result_type, कक्षा में उपस्थित होने धारणा है कि सभी भार के हैं, जबकि विभिन्न प्रकार स्वीकार करने, सभी एक प्रकार इस के साथ संगत वापसी के साथ result_type

और निश्चित रूप से कुछ प्रकार दिए गए T0 ... Tn, std::result_of<functor(T0, ..., Tn)>::type पैरामीटर प्रकार से संबंधित रिटर्न प्रकार देता है।


मामले में जहां operator() के ठीक एक अधिभार मौजूद है [1], आप operator() सदस्य लेने के लिए और निरीक्षण कि सकते हैं

struct not_overloaded { 
    double 
    operator()(double) const; 
}; 

template<typename T> 
struct functor_traits { 
    typedef decltype(&T::operator()) type; 
}; 

functor_traits<not_overloaded>::type यहाँ double (not_overloaded::*)(double) const टाइप किया है, और प्रयास की सिर्फ एक बिट के साथ आप इस से निकाल सकते हैं कि आप क्या चाहते। (उदाहरण के रूप Ret (T::*)(Args...) const की एक विशेषज्ञता है कि प्रकार से मेल खाएगी।)

[1]: लेकिन एक functor परोक्ष भी एक समारोह सूचक/संदर्भ में परिवर्तित करने, ताकि आप उस

+0

इस उत्तर में कुछ इस बारे में क्या है: http://stackoverflow.com/questions/4170201/c0x-overloading-on-lambda-arity/4196447#4196447 यह ओवरलोडिंग का उपयोग कर रहा है, लेकिन शायद कुछ ऐसा ही विशेषज्ञता के लिए काम कर सकता है? – metal

+1

@mlimber मैंने वास्तव में यह जवाब देने के लिए अपना जवाब संपादित किया कि –

+0

इसके लिए धन्यवाद! – metal

1
+1

मैं याद आती है हो सकता है भी द्वारा कार्यक्षमता प्रदान कर सकते हैं पैरामीटर प्रकार और हस्ताक्षर की आवश्यकता है। – metal

संबंधित मुद्दे