2016-10-25 14 views
5

17 अंतिम सुविधाओं ग की ++ this सारांश पढ़ने में बाध्यकारी संरचित मैं थोड़ा संरचित बाइंडिंग पर धारा (जोर मेरा) से हैरान था:std :: टाई दुरुपयोग को बदलने के लिए

संरचित बाइंडिंग

अब तक, परिणाम प्रकार से निपटने के बजाय मैन्युअल रूप से अलग-अलग चरों को टुपल या जोड़ी असाइन करने के लिए std :: टाई का दुरुपयोग करने के लिए एक ज्ञात चाल थी। यह एक हैक था, और चर भी मौजूद थे, अब आप चर घोषित कर सकते हैं और उन्हें एक पंक्ति में प्रारंभ कर सकते हैं:

ऑटो [ए, बी, सी] = getvalues ​​();

ब्रेसिज़ की आवश्यकता है, getvalues ​​एक tuple देता है। std :: जोड़ी प्रस्ताव में उल्लिखित नहीं है, इसलिए यह अस्पष्ट है कि यह जोड़ी के साथ काम करता है, जिसे कुछ डालने के तरीकों में एसटीएल द्वारा वापस किया जाता है।

मैं यह सोचते हैं रहा हूँ वे std::bind

int a,b,c; 
std::tie(a,b,c) = std::make_tuple(1,2,3); 

के उपयोग के इस प्रकार जो मैं एक सिफारिश अभ्यास माना जा रहा देखें।

क्या कोई स्पष्टीकरण प्रदान कर सकता है कि वे उपरोक्त उदाहरण को हैक के रूप में क्यों संदर्भित कर रहे हैं?

+1

उस उद्धृत पाठ में अल्पविराम विभाजन असहनीय हैं! –

उत्तर

15

मैं यह बस उस तरह रख सकते हैं:

एक भाषा में, जहां कार्यों लौट सकते हैं सिर्फ एक चर

int a,b,c; 
std::tie(a,b,c) = function_returning_multiple_values(); 

के लिए एक हैक है:

auto [a, b, c] = function_returning_multiple_values(); 

सिर्फ काल्पनिक में के रूप में दुनिया जहां सी ++ कार्यों के लिए केवल एक पैरामीटर की अनुमति देगा

int p1, p2, p3; 
p1 = ...; 
p2 = ...; 
p3 = ...; 

function_taking_multiple_params(std::tie_params(p1, p2, p3)); 

के लिए एक हैक होगा:

function_taking_multiple_params(p1, p2, p3) 

आप सी ++ प्रतिबंध यह है कि एक समारोह सबसे एक वस्तु पर लौट सकते हैं के साथ इतना आदी रहे हैं, लेकिन वास्तव में यह बस के रूप में सिर्फ एक कृत्रिम भाषा प्रतिबंध नहीं है, अधिकतर पैरामीटर पर स्वीकार करने का प्रतिबंध एक कृत्रिम भाषा प्रतिबंध होगा।

std::tie एक लापता भाषा सुविधा के लिए लाइब्रेरी हैक है। और यह कुछ कमियां भी हैं:

  • चर पहले से घोषित करने की जरुरत
  • वैरिएबल प्रकार स्पष्ट रूप से घोषित किया जाना चाहिए
  • अकुशल या प्रकार के साथ नहीं किया जा सकता है कि डिफ़ॉल्ट constructible नहीं कर रहे हैं

क्या संरचित बाइंडिंग वे सब कुछ हो सकते हैं?नहीं, लेकिन ज्यादातर मामलों के लिए वे सब कुछ हमें चाहिए।

क्या गुम है?

  • कुछ तत्वों के लिए स्पष्ट प्रकार: उदाहरण के लिए:
auto [a, std::string b, c] = foo(); 

जहां a और c प्रकार निष्कर्ष निकाला और b स्पष्ट "std :: स्ट्रिंग"

  • नेस्टिंग है । उदा .:
auto [a, [b1, b2], c] = foo(); 

जहां foo से दूसरे लौटे वस्तु एक tuple वस्तु की तरह है।

  • वापसी स्थल पर भाषा सुविधा (std::tuple सब एक साथ दरकिनार):
auto foo() -> [int, int] 

बजाय

की
auto foo() -> std::tuple<int, int> 
  • नाम वापसी वस्तुओं
auto foo() -> [int& key, int& value] 

... ठीक है ... नहीं है कि अच्छा

  • हो सकता है और गठबंधन के साथ ... होगा - सामान्यीकृत वापसी आरंभ - एक नया आकर्षक नाम के लिए तैयार हो जाओ:
auto minmax_element(It begin, It end) -> [It min_it, It max_it]; 

auto [min = *min_it, max = *max_it] = minmax_element(...); 
+0

'function_returning_multiple_values ​​() 'का हस्ताक्षर क्या होगा? –

+0

@EmeraldWeapon: यह कुछ ऑब्जेक्ट वापस करेगा जो संरचित बाध्यकारी चल रहा है। 'Std :: tie' उदाहरण के लिए, यह प्रकार के' std :: tuple' को वापस कर देगा। –

+0

ठीक है, तो फिर भी सी ++ 17 में कोई वास्तविक एकाधिक वापसी मूल्य नहीं होगा? –

0

अपने आप में std::tie एक और कार्यक्षमता है।

यह चर

को संदर्भ के साथ एक टपल बनाने के लिए चाहिए था अपने तर्कों या एसटीडी के उदाहरण के लिए lvalue संदर्भ उपस्थित टपल बनाता :: ध्यान न दें।

यह चर की प्रतिलिपि किए बिना ऑन-द-फ्लाई टुपल्स बनाने के लिए उपयोगी है क्योंकि वे संदर्भ हैं। मैं सिर्फ उपयोग के लिए cppreference से उदाहरण लेता हूं।

bool operator<(const S& rhs) const 
{ 
    // compares n to rhs.n, 
    // then s to rhs.s, 
    // then d to rhs.d 
    return std::tie(n, s, d) < std::tie(rhs.n, rhs.s, rhs.d); 
} 

यहां टुपल्स बनाए गए हैं लेकिन वे चर की प्रतिलिपि नहीं बनाते हैं लेकिन संदर्भ हैं।

अब क्योंकि वे संदर्भ आप "हैक" कर सकता है पकड़ यह इस

int a,b,c; 
std::tie(a,b,c) = std::make_tuple(1,2,3); 

की तरह कुछ करने के लिए यह अपने आप में संदर्भ के साथ एक को लौट टपल के मूल्यों प्रदान करती है।

यह वह जगह है भी cpprefence सिर्फ एक "नोट" के रूप में उल्लेख पर

std :: टाई क्योंकि std :: टपल जोड़े से परिवर्तित असाइनमेंट है एक std :: जोड़ी खोल करने के लिए इस्तेमाल किया जा सकता है

तो सी ++ में वास्तव में मूल्यों को सीधे असाइन करने का आधिकारिक तरीका नहीं था, लेकिन std::tie इस के रूप में उपयोग किया जा सकता है लेकिन संभवतः इस तरह से उपयोग नहीं किया जा सकता था।

इसलिए उन्होंने नया "संरचित बाध्यकारी" पेश किया।

चाहे std::tie का उपयोग इस तरह किया जाना था या "हैक" व्यक्तिगत राय हो सकती है, मुझे लगता है कि std::tie पेश करने वाले लोगों को इसके लिए सबसे अच्छा पता है। लेकिन उस उदाहरण में std::tie को संरचित बाध्यकारी प्रकार की प्रतिस्थापन के तरीके पर विचार करते हुए, वे एक ऐसे समाधान के साथ आए जो उन्हें लगता है कि बेहतर है।

+0

Boost.Tuple दिखाता है ['बूस्ट :: टाई'] के लिए प्राथमिक उदाहरण के रूप में tuple अपघटन] (http://www.boost.org/doc/libs/1_61_0/libs/tuple/doc/tuple_users_guide.html#tiers)। वास्तव में, यह 'बूस्ट :: टाई' के उपयोग के लिए * केवल उदाहरण * है। –

+0

@ निकोलबोलस वैसे यह 'std :: tie' के बारे में था और इसे संदर्भित लेख में "हैक" क्यों माना जाता है। यह एक स्पष्टीकरण में क्यों लोग इस तरह सोच सकते हैं। मैंने यह संकेत देने के लिए उद्धरण चिह्नों में "हैक" भी लगाया है कि इसे एक हैक के रूप में नहीं देखा जा सकता है लेकिन कुछ इसे इरादे के रूप में देख सकते हैं। जवाब के बावजूद मैं इसे संपादित कर दूंगा। – Hayt

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