2017-10-22 10 views
14

यह कैसे std::thread निर्माता घोषित (विजुअल स्टूडियो 2015 का उपयोग) है:std :: थ्रेड कन्स्ट्रक्टर तीसरा टेम्पलेट पैरामीटर का उद्देश्य क्या है?

template<class _Fn, 
class... _Args, 
class = typename enable_if< 
    !is_same<typename decay<_Fn>::type, thread>::value>::type> 
explicit thread(_Fn&& _Fx, _Args&&... _Ax) 

नहीं _Fn और _Args के बारे में सवाल यह है कि तीसरे class = ... मुझे पूरी तरह से भ्रमित। यह क्या करता है, यह कैसे काम करता है और इसके लिए क्या है?

+3

जाहिर है, यह '_Fn' प्रकार' std :: thread' के मामले में इस कन्स्ट्रक्टर को अक्षम कर रहा है; मुझे संदेह है कि यह कॉपी कन्स्ट्रक्टर के साथ संदिग्ध कॉल त्रुटियों से बचने के लिए है। –

उत्तर

16

यह सशर्त रूप से SFINAE का उपयोग करके ओवरलोड को सक्षम करने का एक उदाहरण है।

यह अधिभार ओवरलोड रिज़ॉल्यूशन के लिए नहीं माना जाना चाहिए यदि पहला तर्क std::thread प्रकार का है।

ध्यान दें कि सी ++ मानक शीर्षलेख का कच्चा स्रोत पढ़ने का इरादा नहीं है। यह भी नकल करने का इरादा नहीं है। सी ++ कंपाइलर कार्यान्वयनकर्ता अपने std हेडर कार्यान्वयन में कई चीजें कर सकते हैं जिन्हें आप उन शीर्षकों के बाहर नहीं कर सकते हैं और नहीं करना चाहिए। जिनमें से कम से कम _ के साथ एक चर शुरू कर रहा है जिसके बाद ऊपरी केस अक्षर (जिसे उपयोगकर्ता कोड में प्रतिबंधित किया गया है)।

_Fn एक std::thread है, जो एक संदर्भ है, या एक सीवी संशोधित के संदर्भ में डिफ़ॉल्ट तर्क के प्रकार की जांच करें।

typename enable_if< 
!is_same<typename decay<_Fn>::type, thread>::value>::type> 

decay<_Fn>::type स्ट्रिप्स संदर्भ और सीवी योग्यता। यह पॉइंटर्स-टू-फ़ंक्शन और पॉइंटर्स-टू-फर्स्ट-एलिमेंट के संदर्भ-टू-एरे के संदर्भ-से-फ़ंक्शंस को भी परिवर्तित करता है, लेकिन यह यहां महत्वपूर्ण नहीं है।

मान लीजिए _Fnthread& था। मैं evalulate देगा:

typename enable_if< 
!is_same<typename decay<thread&>::type, thread>::value>::type> 
typename enable_if< 
!is_same<thread, thread>::value>::type> 
typename enable_if< 
!true>::type> 
typename enable_if< 
false>::type> 
/* substitution failure occurs */> 

enable_if<B>::type केवल मौजूद Btrue है; जब _Fn एक धागा है, तो यह झूठा है, इस प्रकार ओवरलोड रिज़ॉल्यूशन के दौरान प्रतिस्थापन विफलता है।

SFINAE का अर्थ है प्रतिस्थापन विफलता एक त्रुटि नहीं है, और संकलक शिकायत करने की बजाय, यह इस अधिभार को विचार से हटा देता है। और thread(thread const&) (जो मुझे विश्वास है =delete एड) इसके बजाय निर्माता पाया जाता है।

5

3 अज्ञात टेम्पलेट पैरामीटर एक डिफ़ॉल्ट मान है, जो SFINAE के माध्यम से constructor of std::thread के निम्नलिखित आवश्यकता को पूरा करने, जब चाल निर्माता लागू किया जा करने का इरादा है अशांति से बचने के लिए प्रयोग किया जाता है।

यह निर्माता अधिभार संकल्प में भाग नहीं लेता है, तो std::decay_t<Function>std::thread रूप में एक ही प्रकार है।

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