2009-11-19 26 views
7

किसी ने पहले ही इस प्रश्न से पूछा है, लेकिन धागा मूल प्रश्न के साथ समाप्त हुआ जिसका जवाब नहीं मिला।टेम्पलेटेड ऑपरेटर() अधिभार सी ++

लगता है कि आप इस है:

template<size_t i, class f_type> 
void call_with_i(f_type f); 

functor_type या तो है:

एक) एक विधि निम्न हस्ताक्षर है कि के साथ एक struct:

template<size_t i> operator()() const; 

या, ख) एक ऐसा फ़ंक्शन जो इस तरह दिखता है:

template<size_t i> foo(); 

मैं "call_with_i < 42> (foo)" "foo < 42>()" के बराबर होना चाहता हूँ, लेकिन मैं सही वाक्य रचना ऐसा करने के लिए को समझ नहीं सकता। मैं एक समाधान के साथ संतुष्ट होगा जो सिर्फ (ए) करता है लेकिन (ए) + (बी) महान होगा। मैं पहले से ही इन वाक्यविन्यास की कोशिश की है:

f<i>(); // doesn't work 
f()<i>; // doesn't work 
f.operator<i>(); // doesn't work 
f.operator()<i>; // doesn't work 
f.operator()<i>(); // works on msvc, but doesn't work on gcc. 

कैसे आप स्पष्ट टेम्पलेट तर्क के साथ ऑपरेटर() आह्वान करते हैं? क्या इस तरह से इसे आमंत्रित करने का कोई तरीका है कि एक ही सिंटैक्स एक टेम्पलेटेड फ्री फ़ंक्शन भी कॉल करेगा?

पेज। यदि आप सोच रहे हैं कि मैं इसका उपयोग किसके लिए कर रहा हूं, इसकी वजह यह है कि मैं एक फ़ंक्शन दोहराना लिख ​​रहा हूं, जहां < 10> (f) दोहराता है f (0) तो f (1) ... f (10)। मैं इंडेक्स द्वारा समानांतर में एकाधिक बूस्ट :: फ़्यूज़न वैक्टर के माध्यम से इसे फिर से शुरू करने के लिए उपयोग कर रहा हूं। हाँ, मैं iterators का उपयोग कर सकता था, या मैं सिर्फ नामित सदस्य समारोह का उपयोग कर सकता था, लेकिन मैं अभी भी जवाब जानना चाहता हूँ।

संपादित करें नोट: मैंने सामान को धक्का दिया क्योंकि एक टेम्पलेट मुक्त फ़ंक्शन को एक तर्क के रूप में पास करने से कोई अर्थ नहीं होता है।

+0

इसका उत्तर नहीं दिया गया क्योंकि आप नहीं कर सकते। – GManNickG

उत्तर

13

सदस्य टेम्पलेट एक आश्रित नाम है, क्योंकि इसका अर्थशास्त्र f_type के प्रकार पर निर्भर करता है। इसका मतलब है कि आप, इसी तरह आप कैसे निर्भर योग्य नामों से पहले typename रखना चाहिए करने के लिए ("से कम" टोकन के उपयोग को स्पष्ट करने के लिए) जैसा कि इसके नाम से पहले "टेम्पलेट" रखना चाहिए:

template<size_t i, class f_type> 
void call_with_i(f_type f) { 
    f.template operator()<i>(); 
    // f.template foo<i>(); 
} 

समाधान के लिए, आप एक सहायक प्रकार का उपयोग कर सकते हैं:

template<size_t N> struct size_t_ { }; // or boost::mpl::int_ 

template<size_t i, class f_type> 
void call_with_i(f_type f) { 
    f(size_t_<i>()); 
} 

अब, आप अपने operator() इस प्रकार निर्धारित कर सकते हैं:

template<size_t i> void operator()(size_t_<i>) const { 
    // i was deduced automatically by the function argument. 
} 

यह टेम्प्लेटेड निर्माताओं के लिए काम आता है w के लिए आप f_type()<i>() या कुछ नहीं कर सकते हैं। वे में उस मामले में कटौती करने के लिए होगा।

+0

@ जोहान्स: SFINAE का उपयोग करके फ़ंक्शंस के लिए विशेषज्ञ क्यों नहीं हैं? –

+0

महान काम करता है! अत्यन्त अद्भुत। तुम मेरे मेटा नायक हो आह, और mpl :: int_ का उपयोग करके आपका विचार बाउट भी स्मार्ट है। – Glenn

+0

@ laulaulabs.mp, मदद की खुशी है :) –

0
#include <iostream> 

template<size_t i, class f_type> void call_with_i(f_type f); 

struct A { 

    template < size_t i > 
    void operator()() const { 
     /* no link err in demo */ 
    } 

    template < size_t i > 
    void foo() { 
     /* no link err in demo */ 
    } 
}; 

int main(int argc, char * const argv[]) { 
    A f; 

    enum { Constant = 42 }; 

    f.operator()<Constant>(); 
    f.foo<Constant>(); 

    return 0; 
} 

वहाँ एक तरह से यह आह्वान करने के लिए है कि एक ही वाक्य रचना भी एक टेम्प्लेटेड मुक्त समारोह कहेंगे कोई तरीका है?

क्या आप स्पष्टीकरण दे सकते हैं? (छद्म कोड, या कुछ)

+0

वास्तव में टेम्पलेटेड फ्री फ़ंक्शन के बारे में मेरा बिट सिर्फ बकवास है क्योंकि आप फ़ंक्शन टेम्पलेट को तर्क के रूप में पास नहीं कर सकते हैं। – Glenn

1

आपके जैसे मामले में मैं बूस्ट :: फ़ंक्शन को मज़ेदार प्रकार के रूप में उपयोग करता हूं। फिर आप एक ही इंटरफ़ेस को बनाए रखते हुए दोनों फ़ंक्शन ऑब्जेक्ट्स और फ़ंक्शन पॉइंटर्स को पास कर सकते हैं।

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