2009-06-02 15 views
13

इस सरल और व्यर्थ कोड पर विचार करें।सी ++ मज़ेदार और फ़ंक्शन टेम्पलेट

#include <iostream> 

struct A { 
    template<int N> 
    void test() { 
     std::cout << N << std::endl; 
    } 
}; 

int main() { 
    A a; 
    a.test<1>(); 
} 

यह एक समारोह टेम्पलेट की एक बहुत ही सरल उदाहरण है। क्या होगा यदि मैं इसे A::test को एक अधिभारित operator() के साथ एक मज़ेदार बनाने के लिए प्रतिस्थापित करना चाहता था?

#include <iostream> 

struct A { 
    template<int N> 
    void operator()() { 
     std::cout << N << std::endl; 
    } 
}; 

int main() { 
    A a; 
    a<1>(); // <-- error, how do I do this? 
} 

निश्चित रूप से अगर operator() मानकों जो टेम्पलेट पर निर्भर करते थे ले लिया है, संकलक संभवतः टेम्पलेट अनुमान कर सकते हैं। लेकिन मैं पैरामीटर रहित फिक्स्चर के साथ टेम्पलेट पैरामीटर निर्दिष्ट करने के लिए उचित वाक्यविन्यास नहीं समझ सकता।

क्या ऐसा करने का कोई उचित तरीका है?

जाहिर है, इस कोड को काम के बाद से यह functor वाक्य रचना नजरअंदाज होगा:

a.operator()<1>(); 

लेकिन यह है कि जैसे कि इस एक functor :-P होने का उद्देश्य धरा।

a.operator()<1>(); 

वाक्य रचना:

+0

+1: कोड-obfuscation में उपयोग करने के लिए अजीब वाक्यविन्यास कुछ माना है। Http://thc.org/root/phun/unmaintain.html :-) में उल्लेख किया जाना चाहिए –

उत्तर

9

एक और "प्रत्यक्ष" जिस तरह से मैं के अलावा अन्य पता नहीं है। यदि आप कोड को बदलने के लिए खुले हैं, तो कक्षा में टेम्पलेट पैरामीटर को स्थानांतरित करना, या (boost | tr1) :: का उपयोग करना (boost | tr1) :: function object बनाने के लिए बाध्य करेगा।

24

आप केवल

a.operator()<1>(); 

कॉल कर सकते हैं लेकिन यह है कि एक functor का उपयोग नहीं किया जाएगा। फ़ंक्चरर्स को एक गैर टेम्पलेट ऑपरेटर() की आवश्यकता होती है, क्योंकि उन्हें वर्नामे() कहा जा सकता है और यह आपके कोड के साथ काम नहीं करेगा।

#include <iostream> 

template<int N> 
struct A { 
    void operator()() { 
     std::cout << N << std::endl; 
    } 
}; 

int main() { 
    A<1> a; 
    a(); 
} 
2

आप एक वस्तु का एक उदाहरण है, जो जहाँ तक मुझे पता है कि टेम्पलेट पैरामीटर पारित करने के लिए कोशिश कर रहे हैं:

यह एक वास्तविक functor बदलने अपने कोड एक टेम्पलेट वर्ग (functors वर्ग हैं) बनाने के लिए अनुमति नहीं है। आप केवल टेम्पलेट पैरामीटर टेम्पलेट फ़ंक्शंस या टेम्पलेट ऑब्जेक्ट्स को पास कर सकते हैं।

a.test < 1>(); और a.operator() < 1>(); काम क्योंकि वे टेम्पलेट कार्यों के रूप में काम कर रहे हैं।

हालांकि इसे ठीक करने के लिए बूस्ट :: बाइंड (बूस्ट लाइब्रेरीज़ देखें) का उपयोग करें।

struct A { 
    void operator()(int n) { 
     std::cout << n << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) { 
    A a; 
    boost::function<void()> f = boost::bind<void>(a, 1); 
    f(); // prints 1 

    return 0; 
} 

और आपको टेम्पलेट्स के साथ गड़बड़ भी नहीं करना है!

0

नहीं, इसके चारों ओर कोई रास्ता नहीं है। जैसा कि आपने कहा था, आपको या तो ऑपरेटर को स्पष्ट रूप से कॉल करना होगा (जो उद्देश्य को हरा देता है), या टेम्पलेट तर्क संकलक द्वारा कटौती करने में सक्षम होना चाहिए।

1

आप अटक गए हैं। क्या आपने

struct A { 
    template<int N> 
    struct B 
    { 
     void operator()() 
     { std::cout << N << std::endl; } 
    }; 

    template<int N> 
    B<N> functor() {return B<N>();} 
}; 

int main() 
{ 
    A a; 
    a.functor<1>()(); 
} 
संबंधित मुद्दे