// तो क्या: तुम सिर्फ एक std::exception
के मामले में, क्या साधारण के बारे में इलाज के लिए चाहते हैं?
#include <exception>
#include <stdexcept>
#include <iostream>
#include <string>
std::string what(const std::exception_ptr &eptr = std::current_exception())
{
if (!eptr) { throw std::bad_exception(); }
try { std::rethrow_exception(eptr); }
catch (const std::exception &e) { return e.what() ; }
catch (const std::string &e) { return e ; }
catch (const char *e) { return e ; }
catch (...) { return "who knows"; }
}
int main()
{
try { throw std::runtime_error("it's success!"); }
catch (...) { std::cerr << "Here is WHAT happened: " << what() << std::endl; }
try { throw 42; } catch (...) { std::cerr << "and now what: " << what() << std::endl; }
}
क्या यह प्रिंट:
यहाँ क्या है
Here is WHAT happened: it's success!
and now what: who knows
http://coliru.stacked-crooked.com/a/1851d2ab9faa3a24
तो यह कैच-ऑल खंड में what
प्राप्त करने के लिए अनुमति देता है।
लेकिन अगर अपवाद घोंसला है तो क्या होगा ???
std::string what(const std::exception_ptr &eptr = std::current_exception());
template <typename T>
std::string nested_what(const T &e)
{
try { std::rethrow_if_nested(e); }
catch (...) { return " (" + what(std::current_exception()) + ")"; }
return {};
}
std::string what(const std::exception_ptr &eptr)
{
if (!eptr) { throw std::bad_exception(); }
try { std::rethrow_exception(eptr); }
catch (const std::exception &e) { return e.what() + nested_what(e); }
catch (const std::string &e) { return e ; }
catch (const char *e) { return e ; }
catch (...) { return "who knows"; }
}
here से उदाहरण का उपयोग: यहाँ क्या है
#include <fstream>
...
// sample function that catches an exception and wraps it in a nested exception
void open_file(const std::string& s)
{
try {
std::ifstream file(s);
file.exceptions(std::ios_base::failbit);
} catch(...) {
std::throw_with_nested(std::runtime_error("Couldn't open " + s));
}
}
// sample function that catches an exception and wraps it in a nested exception
void run()
{
try {
open_file("nonexistent.file");
} catch(...) {
std::throw_with_nested(std::runtime_error("run() failed"));
}
}
int main()
{
try { throw std::runtime_error("success!"); }
catch (...) { std::cerr << "Here is WHAT happened: \"" << what() << '\"' << std::endl; }
try { run(); }
catch (...) { std::cerr << "what happened for run: \"" << what() << '\"' << std::endl; }
}
क्या छपा है:
Here is WHAT happened: "success!"
what happened for run: "run() failed (Couldn't open nonexistent.file (basic_ios::clear))"
http://coliru.stacked-crooked.com/a/901a0c19297f02b5
लेकिन क्या हुआ अगर प्रत्यावर्तन बहुत गहरा? क्या होगा अगर stackoverflow?अनुकूलित क्या:
#include <typeinfo>
template <typename T>
std::exception_ptr get_nested(const T &e)
{
try
{
auto &nested = dynamic_cast<const std::nested_exception&>(e);
return nested.nested_ptr();
}
catch (const std::bad_cast &)
{ return nullptr; }
}
#if 0 // alternative get_nested
std::exception_ptr get_nested()
{
try { throw ; }
catch (const std::nested_exception &e) { return e.nested_ptr(); }
catch (...) { return nullptr ; }
}
#endif
std::string what(std::exception_ptr eptr = std::current_exception())
{
if (!eptr) { throw std::bad_exception(); }
std::string whaaat;
std::size_t num_nested = 0;
next:
{
try
{
std::exception_ptr yeptr;
std::swap(eptr, yeptr);
std::rethrow_exception(yeptr);
}
catch (const std::exception &e) { whaaat += e.what() ; eptr = get_nested(e); }
catch (const std::string &e) { whaaat += e ; }
catch (const char *e) { whaaat += e ; }
catch (...) { whaaat += "who knows"; }
if (eptr) { whaaat += " ("; num_nested++; goto next; }
}
whaaat += std::string(num_nested, ')');
return whaaat;
}
ही क्या:
Here is WHAT happened: "success!"
here is what: "run() failed (Couldn't open nonexistent.file (basic_ios::clear))"
http://coliru.stacked-crooked.com/a/32ec5af5b1d43453
युपीडी
इसी तरह की सुविधा सी ++ 03 में एक चाल का उपयोग करके लागू किया जा सकता है कि अनुमति देता है कैच ब्लॉक के बाहर throw
वर्तमान अपवाद के लिए: https://stackoverflow.com/a/3641809/5447906
फिर std :: upgrade_ptr का असली उपयोग क्या है? – Ram
@Ram इसका उपयोग एक अपवाद संग्रह और प्रतिलिपि बनाने के लिए है (जिसमें मनमाना प्रकार हो सकता है)। यह एक तरह का स्मार्ट सूचक है। कल्पना करें कि यह 'std :: shared_ptr 'जैसा है, बस यह किसी भी प्रकार के किसी भी अपवाद के लिए काम करता है (यही कारण है कि यह किसी भी प्रकार की जानकारी प्रदान नहीं करता है)। यह धागे के बीच अपवादों को प्रसारित करने के लिए विशेष रूप से उपयोगी होता है, जहां उदा। एक 'std :: वादे 'को किसी अन्य थ्रेड में' std :: भविष्य' के मान तक पहुंचने का प्रयास करते समय बाद में पुनर्स्थापित करने के लिए एक असाधारण अपवाद * स्टोर करने की आवश्यकता होती है। –
@Ram अंत में जब भी आप बाद के उपयोग के लिए एक फेंक दिया अपवाद स्टोर करना चाहते हैं तो यह उपयोगी होता है (आमतौर पर कैच ब्लॉक समाप्त होने के बाद इसे नष्ट कर दिया जाएगा)। [यह] देखें (http://en.cppreference.com/w/cpp/error/exception_ptr) और इसके संबंधित पृष्ठ। –