2012-08-08 12 views
17

मैं void operator()() की कार्यक्षमता के बारे में उलझन में हूं।शून्य ऑपरेटर की कार्यक्षमता()()

तुम मुझे उस के बारे में बता सकते हैं, उदाहरण के लिए:

class background_task 
{ 
public: 

    void operator()() const 
    { 
     do_something(); 
     do_something_else(); 
    } 
}; 

background_task f; 

std::thread my_thread(f); 

यहाँ, क्यों हम operator()() की ज़रूरत है? पहले और दूसरे () का अर्थ क्या है? असल में, मैं सामान्य ऑपरेटर के संचालन को जानता हूं, लेकिन यह ऑपरेटर उलझन में है।

उत्तर

17

पहला () ऑपरेटर का नाम है - यह ऑपरेटर है जब आप ऑब्जेक्ट पर () का उपयोग करते हैं। दूसरा () पैरामीटर के लिए है, जिनमें से कोई भी नहीं है।

background_task task; 
task(); // calls background_task::operator() 
+0

ठंडा, अब और अधिक स्पष्ट है। –

+0

क्या इस स्पष्ट कॉल कार्य() को छोड़कर ऑपरेटर()() के लिए कोई निहित कॉल है? –

+1

@ forester2012, आपको हमेशा इसे स्पष्ट रूप से कॉल नहीं करना चाहिए, हालांकि आप अधिक अजीब 'task.operator()() 'वाक्यविन्यास का भी उपयोग कर सकते हैं। कई मानक एल्गोरिदम हैं जो इस ऑपरेटर को आंतरिक रूप से कॉल करेंगे। –

21

आप () ऑपरेटर को ओवरलोड अपने वस्तु कॉल करने के लिए कर सकते हैं जैसे कि यह एक फ़ंक्शन था::

class A { 
public: 
    void operator()(int x, int y) { 
     // Do something 
    } 
}; 

A x; 
x(5, 3); // at this point operator() gets called 

तो सबसे पहले कोष्ठकों हैं

यहाँ कैसे आप इसका इस्तेमाल होता है, इसका एक उदाहरण हमेशा खाली: यह फ़ंक्शन का नाम है: operator(), दूसरे कोष्ठक में पैरामीटर हो सकते हैं (जैसा कि मेरे उदाहरण में है), लेकिन उन्हें (जैसा कि आपके उदाहरण में) नहीं है।

तो इस ऑपरेटर को अपने विशेष मामले में कॉल करने के लिए आप task() जैसे कुछ करेंगे।

+0

ठंडा, आपकी व्याख्या मुझे अब स्पष्ट करती है –

+0

ऑपरेटर()() केवल किसी भी पैरामीटर के बिना बुलाया जाता है? क्या इसे चलाने के लिए कोई अन्य मामला है? –

+1

@ forester2012, आपको यह चुनने के लिए मिलता है कि पैरामीटर को दूसरे '()' के भीतर पैरामीटर घोषित करके कितने पैरामीटर हैं। आप विभिन्न पैरामीटर सूचियों के साथ अलग-अलग 'ऑपरेटर()' फ़ंक्शंस भी घोषित कर सकते हैं और C++ इसे कॉल करते समय उपयोग किए जाने वाले पैरामीटर के आधार पर सही एक का चयन करेंगे। –

6

पहला भाग operator() उस समारोह को घोषित करने का तरीका है जिसे किसी समारोह के रूप में कक्षा के उदाहरण के रूप में बुलाया जाता है। कोष्ठक की दूसरी जोड़ी में वास्तविक तर्क होंगे। धागा, यानी जो कुछ भी है अंदर

class Adder{ 
public: 
int operator()(int a, int b){ 
    //operator() -- this is the "name" of the operator 
    //   in this case, it takes two integer arguments. 
    return a+b; 
} 
}; 
Adder a; 
assert(5==a(2,3)); 

इस संदर्भ में, std::thread आंतरिक रूप से लागू करेगा f() अंदर operator() के शरीर क्या हो जाता है:

एक वापसी मान और तर्क के साथ

इस में थोड़ा और अधिक समझ कर सकता है उस धागे के अंदर किया।

1

ऊपर दिए गए सभी संकेत अनुक्रमिक कार्यक्रमों के लिए सही हैं, मेरा मतलब है, धागे के बिना कार्यक्रम। धागे का उपयोग चीजों को बदलना। सबसे पहले, std :: थ्रेड के डिफ़ॉल्ट पैरामीटर द्वारा फ़ंक्शन और फ़ंक्शंस पैरामीटर हैं। शायद आप पुस्तक "कार्रवाई में सी ++ संगामिति" अध्ययन कर रहे थे, और लेखक एक दिलचस्प उदाहरण दिखाता है:

void do_some_work(); 
thread my_thread(do_some_work); //thread receives the function address 

इस समारोह मान लीजिए:

शून्य do_other_job (पूर्णांक कश्मीर); कोड के शरीर में, आप क्या करना चाहिए:

k=3; 
thread my_thread2(do_other_job, k); 

आदेश एक और धागा अंडे में।

तो, थ्रेड का उपयोग करके कंपाइलर f (std :: thread my_thread (f);) डिफ़ॉल्ट रूप से कक्षा के बजाय फ़ंक्शन के रूप में व्याख्या करता है। इसे बदलने के लिए आपको एक क्लास के साथ काम कर रहे संकलक को चेतावनी देने के लिए ऑपरेटर() शुरू करना होगा। एक वैकल्पिक कोड हो सकता है:

class background_task{ 
public: 
background_task(){ 
do_sth(); 
do_sth_else(); 
} 
void operator()(){} 
}; 
background_task f; 
thread mythread10(f); 

आखिरकार, यह सही नहीं है, धागे का उपयोग कर, ऑपरेटर खिला है, इसलिए इस कोड काम नहीं करता:

void operator()(int x){ 
do_sth(); 
cout<<"x = "<<x<<endl; 
} 

यह अंदर सभी कोड वजह से होता ब्रैकेट केवल पढ़ने के लिए होते हैं, और रन-टाइम के दौरान बदला नहीं जा सकता है। यदि आप कन्स्ट्रक्टर में एक चर डालने का लक्ष्य रखते हैं, तो इसे थ्रेड प्रारंभ में रखा जाना चाहिए। तो:

class backg{ 
public: 
backg(int i){ 
    do_sth(i); 
    } 
void operator()(){} 
}; 
int main(){ 
thread mythread{ backg(12) }; //using c++11 
return 0; 
} 

गलतियों के बिना चलाएगा, और थ्रेड में फंक्शन do_sth (12) निष्पादित करेगा।

मुझे उम्मीद है कि मैंने मदद की है।

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