2012-01-11 12 views
5

मेरे पास एक ऐसा एप्लिकेशन है जहां मैं एक फ़ंक्शन, marshal_and_apply बना रहा हूं, जो कुछ तर्कों के साथ कुछ अन्य फ़ंक्शन (या फ़ैक्टर), f कहता है। marshal_and_apply का काम f के पैरामीटर के प्रकार के आधार पर तर्कों के लिए कुछ विशेष मार्शलिंग लागू करना है।फ़ंक्शन के पैरामीटर के प्रकारों का निरीक्षण कैसे करें?

f के मानकों में से एक एक विशेष प्रकार, marshal_me<T> की है, तो marshal_and_apply कुछ विशेष रूप से आवंटित भंडारण के माध्यम से पैरामीटर यह f को पार करने से पहले मार्शल होगा। आवंटन करने के लिए, सभी मानकों की भंडारण आवश्यकताओं को किसी भी मार्शल से पहले marshal_and_apply पर जाना जाना चाहिए।


कुछ उदाहरण:

template<typename Function, typename... Args> 
void marshal_and_apply(Function f, Args... args); 

void func1(int x, int y); 
void func2(marshal_me<int> x, int y); 
void func3(marshal_me<int> x, marshal_me<int> y, marshal_me<int> z); 

// this call would be equivalent to: 
// func1(7,13) 
marshal_and_apply(func1, 7, 13); 

// this call would be equivalent to: 
// auto storage = my_allocator(sizeof(int)); 
// auto x = marshal_me<int>(7, storage); 
// func2(x, 13); 
marshal_and_apply(func2, 7, 13); 

// this call would be equivalent to: 
// auto storage = my_allocator(sizeof(int) + sizeof(int) + sizeof(int)); 
// auto x = marshal_me<int>(7, storage); 
// auto y = marshal_me<int>(13, storage + sizeof(int)); 
// auto z = marshal_me<int>(42, storage + sizeof(int) + sizeof(int)); 
// func3(x,y,z); 
marshal_and_apply(func3, 7, 13, 42); 

इस समस्या को हल करने के लिए, ऐसा लगता है कि marshal_and_applyf के मापदंडों के प्रकार के निरीक्षण करने के लिए एक तंत्र की आवश्यकता है। मुझे संदेह है कि यह सामान्य रूप से संभव नहीं है, लेकिन यह पहचानना संभव हो सकता है कि किस प्रकार के विशेष सेट में से एक (इस मामले में, marshal_me<T>) किसी विशेष पैरामीटर के प्रकार में परिवर्तनीय है।

मुझे marshal_and_apply कैसे बनाना चाहिए?

+0

आपके दूसरे उदाहरण में, मैं नहीं देख सकता कि आपने '7' के साथ क्या किया है। क्या आपका मतलब था 'ऑटो एक्स = marshal_me (स्टोरेज, 7); या कुछ? –

+0

@AaronMcDaid हां, मैंने इसे सही कर दिया है। –

+0

यदि 'marshal_me ' में एक कंस्ट्रक्टर 'int' ले रहा है, तो आप 'func2 (7, 13)' को वैसे भी कॉल कर सकते हैं। रैपर क्या अतिरिक्त लाभ है? –

उत्तर

4

हो सकता है कि कुछ इस तरह:

template<typename Function, typename... Args> 
void marshal_and_apply(Function f, Args &&... args) 
{ 
    f(InspectAndModify<Args>::process(sizeof...(Args), std::forward<Args>(args))...); 
} 

अब निर्धारित करें:

template <typename T> struct InspectAndModify 
{ 
    static T&& process(unsigned int N, T && t) 
    { 
     return std::forward<T>(t); 
    } 
}; 

template <typename T> struct InspectAndModify<marshal_me<T>> 
{ 
    static T&& process(unsigned int N, marshal_me<T> && m) 
    { 
     /* ... */ 
    } 
}; 

कुछ पूरी तरह से अलग: यह दृष्टिकोण पहले समारोह हस्ताक्षर dissects, और फिर प्रदर्शन करती एक "स्थिर बदलना "प्रत्येक जोड़ी प्रकार पर, जहां आप marshal_me विशेषज्ञता डाल सकते हैं:

template <typename T> struct marshal_me { marshal_me(T) { } }; 

template <typename To, typename From> struct static_transform; 

template <typename T> struct static_transform<T, T> 
{ 
    static T go(T t) { return t; } 
}; 

template <typename T> struct static_transform<T, T&> 
{ 
    static T go(T & t) { return t; } 
}; 

template <typename T> struct static_transform<marshal_me<T>, T> 
{ 
    static marshal_me<T> go(T && t) { return std::forward<T>(t); } 
}; 

template<typename T, typename... Args> 
struct marshal_impl 
{ 
    template <typename ...Urgs> 
    static T go(T(*f)(Urgs...), Args &&... args) 
    { 
    return f(static_transform<Urgs, Args>::go(std::forward<Args>(args))...); 
    } 
}; 

template<typename Function, typename... Args> 
void marshal_and_apply(Function f, Args &&... args) 
{ 
    marshal_impl<void, Args...>::go(static_cast<typename std::decay<Function>::type>(f), 
            std::forward<Args>(args)...); 
} 
+0

धन्यवाद! वह काम करेगा, लेकिन मुझे डर है कि यह तीसरे उदाहरण को हल नहीं करेगा। '' निरीक्षक और संशोधित करें :: प्रक्रिया'' को उन किसी भी प्रक्रिया को संसाधित करने से पहले प्रक्रियाओं की कुल संख्या को जानने की आवश्यकता है। –

+0

@ जेरेडबॉबरॉक: क्या आप एक अतिरिक्त पैरामीटर के रूप में 'sizeof ... (Args)' पास कर सकते हैं? –

+0

किस समारोह में? '' 'Marshal_and_apply''' का हस्ताक्षर तय किया गया है, लेकिन यह' '' निरीक्षण और मोडिफाइफ़ :: प्रक्रिया'' 'के लिए अतिरिक्त जानकारी पास कर सकता है। –

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