2015-08-20 3 views
6

मुझे अपने सी ++ कोड में std :: experimental :: वैकल्पिक का उपयोग करना पसंद है, लेकिन समस्या यह है कि value_or को डिफ़ॉल्ट मान के समान प्रकार के डिफ़ॉल्ट मान की आवश्यकता होती है।सी ++ जंग के परिणाम <T, E> प्रकार के बराबर?

यह बहुत अच्छी तरह से काम नहीं करता है जब मैं एक वैकल्पिक चाहते है कि या तो एक पूर्णांक है या वह किसी त्रुटि संदेश में शामिल है।

मुझे लगता है कि मैं एक यूनियन स्ट्रक्चर का उपयोग कर सकता हूं जिसमें यह इंगित करने के लिए एक बूलियन है कि क्या मूल्य है या यह एक त्रुटि है, लेकिन यह सुनिश्चित होगा कि सी ++ में सिर्फ Result<T, E> रस्ट की तरह टाइप किया गया हो।

क्या ऐसा कोई प्रकार है? बूस्ट ने इसे लागू क्यों नहीं किया है?

परिणाम वास्तव में विकल्प से अधिक उपयोगी है, और निश्चित रूप से बूस्ट के लोग इसके अस्तित्व से अवगत हैं। शायद मैं जंग के कार्यान्वयन को पढ़ूंगा और फिर इसे सी ++ में कॉपी करूंगा?

पूर्व:

// Function either returns a file descriptor for a listening socket or fails 
// and returns a nullopt value. 
// My issue: error messages are distributed via perror. 
std::experimental::optional<int> get_tcp_listener(const char *ip_and_port); 
// You can use value_or to handle error, but the error message isn't included! 
// I have to write my own error logger that is contained within 
// get_tcp_listener. I would really appreciate if it returned the error 
// message on failure, rather than an error value. 
int fd = get_tcp_listener("127.0.0.1:9123").value_or(-1); 
// Rust has a type which does what I'm talking about: 
let fd = match get_tcp_listener("127.0.0.1:9123") { 
    Ok(fd) => fd, 
    Err(msg) => { log_error(msg); return; }, 
} 
+2

संभावित रूप से प्रस्तावित 'std :: अपेक्षित', या किसी अन्य 'अपेक्षित' किसी के लागू किए गए प्रकार। – chris

+0

सी ++ में एक अभिव्यक्ति का संकलन समय पर ज्ञात एक प्रकार होना चाहिए; यह या तो 'int' या स्ट्रिंग नहीं हो सकता है। –

+2

एक चीज की तुलना में एक चीज अधिक उपयोगी कैसे होती है जब वे पूरी तरह से असंबंधित, ऑर्थोगोनल समस्याओं का समाधान करते हैं? 'वेक्टर' 'cout' से अधिक उपयोगी है? – Barry

उत्तर

15

optional<T>T और शून्य (nullopt_t) की एक असममित प्रकार सुरक्षित संघ है। यदि आप explicit operator bool के साथ T प्राप्त करते हैं, तो आप क्वेरी कर सकते हैं और * के साथ T प्राप्त करें। विषमता का अर्थ है कि वैकल्पिक "पसंदीदा" T होने के लिए, यही कारण है कि अयोग्य संचालन (जैसे * या ऑपरेटर बूल) T नेस का संदर्भ लें।

variant<A,B,C> from paper n4218A, B और C (आदि) का एक सममित प्रकार सुरक्षित संघ है। boost::variant हमेशा व्यस्त रहता है, और std::experimental::variantलगभग हमेशा व्यस्त है।

यह सममित है, वहाँ एकल * वापस जाने के लिए के लिए कोई अद्वितीय प्रकार है, और explicit operator bool ब्याज की ज्यादा नहीं कह सकता, इसलिए कोई भी समर्थित हैं।

इसके बजाय, आपको इसे देखना होगा, या विशेष प्रकार के लिए पूछना होगा।

std::experimental::expected<E, T> from paper n4015 एक असममित प्रकार-सुरक्षित संघ है। यह या तो T है, या E है। लेकिन optional की तरह, यह T होने के लिए "पसंद करता है"; इसमें explicit operator bool है जो आपको बताता है कि यह T है, और यूनरी *T प्राप्त करता है।

एक अर्थ में, expected<E,T> एक optional<T> है, लेकिन जब अंतरिक्ष को बर्बाद करने के बजाय खाली होता है तो यह E स्टोर करता है, जिसे आप क्वेरी कर सकते हैं।

Result<T,E>expected<E,T> के करीब लगता है (ध्यान दें कि n4015 के रूप में, Result की तुलना में पैरामीटर का क्रम बदल दिया गया है)।

+0

वाह जानकारी के लिए धन्यवाद! आप सभी वास्तव में मददगार रहे हैं! –

+1

अपेक्षाकृत बनाम वैकल्पिक बनाम संस्करण का एक बहुत अच्छा संक्षेप स्पष्टीकरण। लगता है कि मेरे द्वारा पोस्ट की गई बातचीत के लिए अपेक्षित प्रस्ताव की समान सामग्री है, और वास्तव में इसका संदर्भ है। दोनों के माध्यम से जाना शायद सार्थक है, अन्यथा आप जिस माध्यम को पसंद करते हैं उसे चुनें। –

3

optional डिजाइन द्वारा कुछ प्रकार या कुछ भी नहीं के एक मूल्य या तो होता है।

आप Boost::Variant की तरह कुछ के लिए देख रहे हैं।

यह नहीं अभी तक मानक पुस्तकालय का हिस्सा है, हालांकि यह कुछ इस तरह अंत में हो सकता है।

+0

यह लगभग एक आदर्श समाधान है, लेकिन मुझे लगता है कि अपेक्षित कार्य के लिए अधिक उपयुक्त है। हालांकि, अपेक्षित अभी तक किसी भी मानक में नहीं है। –

6

क्या आप देख रहे हैं वास्तव में Alexandrescu की उम्मीद है। मैं गहराई से समझने के लिए अपनी बात सुनना चाहता हूं: https://channel9.msdn.com/Shows/Going+Deep/C-and-Beyond-2012-Andrei-Alexandrescu-Systematic-Error-Handling-in-C। वह वास्तव में लाइन द्वारा कार्यान्वयन लाइन के माध्यम से चला जाता है, और आप इसे आसानी से लिख सकते हैं और इसके बाद इसका उपयोग कर सकते हैं।

संस्करण एक अधिक सामान्य उपकरण है, इसे आप जो चाहते हैं उसे करने के लिए मजबूर किया जा सकता है लेकिन आप अपेक्षा से बेहतर हैं।

+0

धन्यवाद, यह वही है जो मैं ढूंढ रहा था! –

+0

"आप इसे आसानी से लिख सकते हैं और इसके बाद इसका उपयोग कर सकते हैं" हां यह एक बहुत ही उपयोगी बात है। विशेष रूप से मैंने परियोजनाओं में अपना पैटर्न इस्तेमाल किया है जहां हमें अपवाद फेंकने से बचना चाहिए। आप एक मानक "त्रुटि संदेश" संरचना बना सकते हैं जो अपवाद की भूमिका निभाता है, और अपनी कक्षा बनाने की कोशिश करता है ताकि वास्तव में त्रुटियों वाली वस्तुओं को पूरी तरह से एक अलग प्रकार में परिवर्तित किया जा सके, या इसे हास्केल की तरह कहीं अधिक करने का प्रयास करें आप मूल रूप से आगंतुकों के साथ बात संभालते हैं। यदि आप इसे संस्करण का उपयोग करने के बजाय स्वयं लागू करते हैं, तो आप इसे move_ctors को सही तरीके से संभाल सकते हैं –

1

यदि न केवल बढ़ावा शामिल है तो आप result का उपयोग कर सकते हैं। यह अच्छा एकल हेडर कंटेनर है।

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