2010-10-15 16 views
11

मेरा प्रश्न इस बात के बारे में है कि नाम का उपयोग किया जाना चाहिए।परिवर्तनीय NAMES टेम्पलेट कैसे करें, प्रकार नहीं?

हो सकता है कि एक सरल & छद्म उदाहरण:

/** 
Does something with a specified member of every element in a List. 
*/ 
template<membername MEMBER> // <-- How to define such thing? 
void doSomething(std::vector<MyClass> all){ 

    for(i=0; i < all.size(); i++) 
     all[i].MEMBER++; // e.g.; use all[i].MEMBER in same way 

} 

और

class MyClass{ 
public: 
    int aaa, bbb, ccc; 
} 

और आवेदन:

main(){ 
    vector<MyClass> all = .... 

    // applicate doSomething() to all aaa's 
    doSomething<aaa>(all); // or: 
    doSomething<MyClass::aaa>(all); // or: 
    doSomething<?????>(all); 
} 

कैसे करना चाहिए टेम्पलेट परिभाषा की तरह दिखता है मैं जो स्विच कर सकते हैं कि MyClass के सदस्य चर (aaa, bbb या ccc) को एक्सेस/संशोधित किया गया है कुछ कुछ(।) ?
मेरे वास्तविक विश्व कार्य में सभी सदस्य उपरोक्त के समान प्रकार के होते हैं।

धन्यवाद, Tebas

उत्तर

17

खाका मापदंडों बाहरी लिंकेज और सदस्य संकेत साथ प्रकार, पूर्णांक स्थिरांक, कार्यों या वस्तुओं की ओर इशारा/संदर्भ के लिए प्रतिबंधित कर रहे हैं - लेकिन कोई पहचानकर्ता।

template<int MyClass::* MemPtr> 
void doSomething(std::vector<MyClass> & all) { 
    for(i=0; i < all.size(); i++) 
     (all[i].*MemPtr)++; 
} 

: 

doSomething<&MyClass::aaa>(all); 

ध्यान दें कि मैं DoSomething समारोह बदल एक संदर्भ लेने के लिए के बजाय मूल्य द्वारा वेक्टर को स्वीकार:

लेकिन आप टेम्पलेट पैरामीटर के रूप में एक सदस्य सूचक इस्तेमाल कर सकते हैं।

+0

धन्यवाद। मूल्य द्वारा 'सभी' कॉल करें प्रश्न के सरलीकरण के लिए था ... लेकिन सदस्य सूचक टेम्पलेट्स द्वारा अनुरोधित संदर्भ द्वारा कॉल किया गया है? या मैं एक प्रति का उपयोग भी कर सकता हूँ? – Tebas

+0

@Tebas: आप एक प्रति का उपयोग कर सकते हैं, लेकिन इसका मतलब है कि 'doSomething' का प्रभाव फ़ंक्शन के बाहर दिखाई नहीं देगा। संदर्भ के अनुसार कॉल का उपयोग यह सुनिश्चित करने के लिए किया गया था कि परिणाम कॉलर के वेक्टर में दिखाई देगा। –

+0

@Tebas: नहीं, इससे कोई फर्क नहीं पड़ता। किसी भी मामले में सभी [i] MyClass टाइप की एक लवली अभिव्यक्ति होगी। – sellibitze

1

मैं इस समस्या को हल करने के लिए लैम्बडा का उपयोग करूंगा। कुछ इस तरह: इस मामले में

#include <vector>  // vector 
#include <algorithm> // for_each 
#include <functional> // function 

struct MyClass { 
    void func1() const { std::cout << __FUNCTION__ << std::endl; } 
    void func2() const { std::cout << __FUNCTION__ << std::endl; } 
}; 

void doSomething(std::vector<MyClass> all, std::function<void (MyClass& m)> f) 
{ 
    std::for_each(all.begin(), all.end(), f); 
} 

int main() 
{ 
    std::vector<MyClass> all; 
    all.push_back(MyClass()); 

    // apply various methods to each MyClass: 
    doSomething(all, [](MyClass& m) { m.func1(); }); 
    doSomething(all, [](MyClass& m) { m.func2(); }); 
} 
बेशक

समारोह doSomething अनावश्यक है। मैं बस पर सीधे all पर कॉल कर सकता था।

10

sellibitze का समाधान ठीक है (हालांकि ईमानदार नहीं होना चाहिए: मेरा संपादन देखें), केवल यह आपको केवल int int के सदस्यों का उपयोग करने के लिए सीमित करता है। एक अधिक सामान्य समाधान इस होगा (हालांकि सदस्य टेम्पलेट पैरामीटर यहाँ नहीं है)

#include <vector> 

struct MyClass 
{ 
    int i; 
    char c; 
}; 

template <class T> 
void DoSomething(std::vector<MyClass>& all, T MyClass::* MemPtr) 
{ 
    for(std::vector<MyClass>::size_type i = 0; i < all.size(); ++i) 
     (all[i].*MemPtr)++; 
} 

int main() 
{ 
    std::vector<MyClass> all; 
    DoSomething(all, &MyClass::i); 
    DoSomething(all, &MyClass::c); 
} 

संपादित करें: इसके अलावा, कृपया ध्यान दें कि यह आम तौर पर किसी सदस्य के लिए एक सूचक के लिए एक अच्छा विचार टेम्पलेट पैरामीटर यद्यपि होने के लिए नहीं है केवल ऐसे पॉइंटर्स जिन्हें संकलित समय ज्ञात किया जा सकता है पारित किया जा सकता है, यह है कि आप पॉइंटर रनटाइम निर्धारित नहीं कर सकते हैं और फिर इसे टेम्पलेट पैरा के रूप में पास कर सकते हैं।

+0

' वेक्टर :: सभी() 'रिटर्न 'size_t' और' हस्ताक्षरित नहीं '- कृपया' i' के लिए' size_t' का उपयोग करें। (Iterators भी बेहतर होगा ...) –

+1

@Steve: मैं पूरी तरह से इटरेटर के बारे में सहमत हूं, मैंने सिर्फ ओप के कोड से टेक्स्ट कॉपी किया है। मैं इसे नहीं बदलूंगा। और आकार() आकार_टी नहीं लौटाता है, यह std :: vector :: size_type देता है। और क्या वेक्टर :: सब?: डी –

+0

ओह, आप बिंदु 1 पर सही हैं और मुझे नहीं पता कि मैं बिंदु 2 पर क्या सोच रहा था। आपके लिए +1। अजीब रूप से पर्याप्त, मैंने अभी * उत्तर दिया * वैक्टर से संबंधित एक प्रश्न और 'size_type' का उपयोग करना जानता था और 'size_t' नहीं। कभी-कभी मैं बुरा हूं। –

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