मेरे पास एक तरीका है जो एक वैकल्पिक संरचना देता है, जैसे:
auto getBook(const std::string &title) const -> std::optional<Book>;
मैं इस विधि को किसी अन्य विधि में कॉल करना चाहता हूं जो वैकल्पिक लेखक देता है। समस्या यह है कि कार्यान्वयन को हमेशा जांचना चाहिए कि क्या गेटबुक द्वारा लौटाया गया वैकल्पिक किसी विधि को कॉल करने से पहले भर जाता है, जैसे:
auto getAuthor(const std::string &title) const -> std::optional<Author>
{
const auto optBook = getBook(title);
if (optBook.has_value)
return optBook->getAuthor();
else
return std::nullopt;
}
क्या इसे छोटे तरीके से लिखने का कोई तरीका है, ताकि यदि वैकल्पिक भर दिया जाए तो विधि कहलाती है, लेकिन यदि वैकल्पिक खाली है, तो std::nullopt
वापस कर दिया जाता है। ऐसा कुछ (मुझे पता है कि यह वर्तमान में काम नहीं करता है लेकिन आपको मेरी बात समझ में आती है):
auto getAuthor(const std::string &title) const -> std::optional<Author>
{
return getBook(title).getAuthor();
}
4 जवाब
आप एक map
फ़ंक्शन बनाकर इस पैटर्न को सामान्य कर सकते हैं, जो एक वैकल्पिक o
और एक फ़ंक्शन f
लेता है, और f(*o)
का परिणाम देता है यदि o.has_value() == true
:
template <typename O, typename F>
auto map(O&& o, F&& f) -> std::optional<decltype(f(*std::forward<O>(o)))>
{
if (!o.has_value())
{
return {std::nullopt};
}
return {f(*std::forward<O>(o))};
}
फिर आप getAuthor
को इस प्रकार परिभाषित कर सकते हैं:
auto getAuthor(const std::string& title) -> std::optional<Author>
{
return map(getBook(title), [](Book b)
{
return b.author;
});
}
मैंने इस तरह के ऑपरेशन के लिए एक लाइब्रेरी बनाई है, जिसका नाम है scelta
ए>। मेरे पुस्तकालय के साथ, आप लिख सकते हैं:
auto getBook(const std::string& title) -> std::optional<Book>;
auto getAuthor(const std::optional<Book>& title) -> std::optional<Author>;
using namespace scelta::infix;
std::optional<Author> a = getBook("...") | map(getAuthor);
अधिक जानकारी के लिए "Monadic वैकल्पिक संचालन" देखें।
मुझे लगता है कि आप जो चाहते हैं उसे वापस कर सकते हैं और रूट फ़ंक्शन में अपवादों को पकड़ सकते हैं, ऐसा कुछ:
auto get_size_t(const bool state)
{
return state ? std::optional<size_t>(std::rand()) : std::nullopt;
}
auto get_string_size_t(const bool state)
{
return std::optional<std::string>(std::to_string(get_size_t(state).value()));
}
void f()
try
{
std::clog << get_string_size_t(true).value() << std::endl;
std::clog << get_string_size_t(false).value() << std::endl;
}
catch (...)
{
}
मुझे लगता है, अशक्त वस्तु यहां कार्य के लिए std::वैकल्पिक के बजाय पैटर्न की आवश्यकता है।
हाँ, यह std :: वैकल्पिक जैसा दिखता है, लेकिन एक अलग अर्थशास्त्र के साथ: जब किसी ऑब्जेक्ट पर किसी भी विधि (जैसे getAuthor) को कॉल किया जाता है, यदि विधि का परिणाम मान्य है, तो वैध ऑब्जेक्ट वापस कर दिया जाता है। यदि नहीं, तो इसके बजाय अशक्त वस्तु वापस कर दी जाती है।
बहुत समय पहले मैंने एक्सएमएल जैसे पेड़ के कार्यान्वयन पर काम नहीं किया था, यह ऐसा कुछ था:
auto val = object.node("root").node("branch_1").node("subbranch_1").toInt();
if (val) process(val.asInt());
नोड () कॉल के प्रत्येक चरण पर, यदि विशिष्ट नोड नहीं मिला, तो अमान्य नोड वापस कर दिया जाता है। जब इसे अमान्य नोड पर बुलाया जाता है, तो अमान्य नोड वापस कर दिया जाता है।
AFAIK, ऐसा कुछ भी वर्तमान में एसटीएल में लागू नहीं किया गया है।
संपादित करें: इसके लिए प्रभावी ढंग से काम करने के लिए, आपको कुछ बेस क्लास से प्राप्त होने वाली किताबों, लेखकों, अध्यायों और अन्य सामानों के सभी उदाहरणों की आवश्यकता है, जो कि शून्य वस्तु होगी।
संपादित करें: यह सभी मामलों के लिए सबसे अच्छा समाधान नहीं है, शायद, यह आपके लिए लागू करने के लिए बहुत जटिल है।
boost::optional
, जिस पर std::optional
आधारित है, उसका एक सदस्य है map
जो ऐसा करता है।
उदा.
auto getBook(const std::string &title) const -> boost::optional<Book>;
auto getAuthor(const std::string &title) const -> boost::optional<Author>
{
return getBook(title).map(std::mem_fn(&Book::getAuthor));
}
संबंधित सवाल
नए सवाल
c++
C ++ एक सामान्य-प्रयोजन प्रोग्रामिंग भाषा है। यह मूल रूप से C के विस्तार के रूप में डिज़ाइन किया गया था और इसमें एक समान सिंटैक्स है, लेकिन यह अब पूरी तरह से अलग भाषा है। C ++ कंपाइलर के साथ संकलित कोड के बारे में प्रश्नों के लिए इस टैग का उपयोग करें। विशिष्ट मानक संशोधन [C ++ 11], [C ++ 14], [C ++ 17], [C ++ 20] या [C ++ 23], आदि से संबंधित प्रश्नों के लिए संस्करण-विशिष्ट टैग का उपयोग करें। ।