हां, यह संभव है:
// we need a compile-time helper to generate indices
template< std::size_t... Ns >
struct indices
{
typedef indices< Ns..., sizeof...(Ns) > next;
};
template< std::size_t N >
struct make_indices
{
typedef typename make_indices< N - 1 >::type::next type;
};
template<>
struct make_indices<0>
{
typedef indices<> type;
};
इन सहायकों के साथ, आप इस तरह अपने कार्य के लिए एक फारवर्डर की जरूरत है:
template<typename R, typename... Args, std::size_t... Ns>
R myFunctionImpl(void *Data, void *function, indices<Ns...>) {
auto f = (R (*)(Args...))function;
return f(read<Args>(Data, Ns + 1)...);// +1 because indices is zero-based
}
template<typename R, typename... Args>
R myFunction(void *Data, void *function) {
return myFunctionImpl< R, Args... >(Data, function, typename make_indices<sizeof...(Args)>::type());
}
संपादित करें: यह कैसे काम करता है? सबसे पहले, हम argument packArgs
के आकार sizeof...
के आकार का निर्धारण करते हैं। make_indices<N>::type
फिर indices<0,1,2,...,N-1>
में फैलता है। इसे कार्यान्वयन फ़ंक्शन के लिए एक अतिरिक्त पैरामीटर के रूप में दिया जाता है (फॉरवर्डर जो सिर्फ डमी इंस्टेंस बनाता है), इसलिए तर्क कटौती कार्यान्वयन फ़ंक्शन की तरफ बढ़ती है और जेनरेटेड इंडेक्स को तर्क पैक Ns
में डालती है।
कार्यान्वयन फ़ंक्शन में अब एक ही आकार के साथ दो तर्क पैक हैं, अर्थात् Args
और Ns
। जब इलिप्सिस ...
के माध्यम से विस्तार किया गया, तो इलिप्सिस संपूर्ण अभिव्यक्ति फैलाता है कि यह लागू होता है और यह समांतर में सभी पैरामीटर पैक फैलाता है! उपर्युक्त उदाहरण में अभिव्यक्ति read<Args>(Data, Ns+1)
है, जो अच्छी तरह से ओपीएस छद्म कोड में फैली हुई है।
स्रोत
2013-03-04 15:13:20
मुझे यकीन है कि आप ऑब्जेक्ट-पॉइंटर से फ़ंक्शन-पॉइंटर कास्ट से बच सकते हैं। – sellibitze
@ सेलिबिटज़: क्या यह एक समस्या है? क्योंकि मेरे पास केवल एक शून्य * सूचक उपयोगकर्ता डेटा हो सकता है जो एक सी फ़ंक्शन से पारित किया जाता है। –
डेटा 'शून्य *' हो सकता है। यह कार्य 'शून्य *' है जो एक चिंता है। –