लाइब्रेरी बुनियादी बातों के लिए सी ++ एक्सटेंशन, संस्करण 2 (N4564) प्रकार std::experimental::source_location
परिचय देता है।कैसे std सकता है :: प्रयोगात्मक :: source_location लागू किया?
§ 14.1.2 [reflection.src_loc.creation] कहते हैं:
static constexpr source_location current() noexcept;
रिटर्न: जब एक समारोह कॉल द्वारा लाया (सी ++ 14 § 5.2.2) जिसका पोस्टफ़िक्स अभिव्यक्ति (संभवत: parenthesized) आईडी अभिव्यक्ति
current
नामकरण है, एक कार्यान्वयन से परिभाषित मूल्य के साथ एकsource_location
देता है। मूल्य द्वारा#line
(सी ++ 14 § 16.4)__LINE__
और__FILE__
के लिए के रूप में एक ही तरीके से प्रभावित किया जाना चाहिए। अगर किसी अन्य तरीके से बुलाया जाता है, तो लौटाया गया मूल्य अनिर्दिष्ट है।टिप्पणी: जब एक ब्रेस या बराबर-प्रारंभकर्ता एक गैर स्थिर डेटा सदस्य प्रारंभ करने में प्रयोग किया जाता है,
current
के लिए किसी भी कॉल निर्माता या कुल आरंभीकरण कि सदस्य initializes के स्थान के अनुरूप होना चाहिए।[नोट: जब एक डिफ़ॉल्ट तर्क (सी ++ 14 § 8.3.6) के रूप में इस्तेमाल किया,
source_location
का मूल्य कॉल स्थल परcurrent
करने के लिए कॉल के स्थान हो जाएगा। — अंत टिप्पणी]
अगर मैं सही ढंग से समझ है, तो सुविधा इस तरह इस्तेमाल किया जा करने का इरादा है।
#include <experimental/source_location> // I don't actually have this header
#include <iostream>
#include <string>
#include <utility>
struct my_exception
{
std::string message {};
std::experimental::source_location location {};
my_exception(std::string msg,
std::experimental::source_location loc = std::experimental::source_location::current()) :
message {std::move(msg)},
location {std::move(loc)}
{
}
};
int
do_stuff(const int a, const int b)
{
if (a > b)
throw my_exception {"a > b"}; // line 25 of file main.cxx
return b - a;
}
int
main()
{
try
{
std::cout << do_stuff(2, 1) << "\n";
}
catch (const my_exception& e)
{
std::cerr << e.location.file_name() << ":" << e.location.line() << ": "
<< "error: " << e.message << "\n";
}
}
अपेक्षित उत्पादन:
main.cxx:25: error: a > b
std::experimental::source_location
के बिना, हम एक सहायक मैक्रो THROW_WITH_SOURCE_LOCATION
कि आंतरिक रूप से अपवाद वस्तु उचित रूप से प्रारंभ करने के लिए __FILE__
और __LINE__
मैक्रो का उपयोग करता है का इस्तेमाल किया है हो सकता है।
मैं सोच रहा था कि कैसे एक पुस्तकालय std::experimental::source_location
को लागू कर सकते हैं। जब तक मैं पूरी तरह से बिंदु खो रहा हूं, ऐसा करने के लिए विशेष संकलक समर्थन के बिना ऐसा संभव नहीं है। लेकिन इस काम को करने के लिए किस प्रकार की जादू कंपाइलर सुविधाओं की आवश्यकता होगी? क्या यह std::initializer_list
के लिए तैनात चाल के तुलनीय होगा? क्या इस सुविधा का कोई प्रयोगात्मक कार्यान्वयन देखने के लिए उपलब्ध है? मैंने the SVN sources for GCC चेक किया है लेकिन अभी तक कुछ भी नहीं मिला है।
संकलक जादू, प्रति 'std :: के रूप में –
@RichardHodges type_info'' typeid' एक काफी सीधी-सपाट समारोह के रूप में लागू किया जा सकता। गैर-पॉलीमोर्फिक प्रकारों के लिए, संकलक पहले से ही जानता है कि उत्तर पॉलिओर्फिक प्रकारों के लिए सीधे स्ट्रिंग अक्षर को सम्मिलित कर सकता है, इसे रन-टाइम पर 'vptr' का पालन करने के लिए सरल कोड उत्पन्न करना होगा। मैं नहीं देखता कि कैसे 'source_location' लागू करने के लिए समान रूप से सरल होगा। लेकिन अगर आप जानते हैं, तो यह वही जवाब है जिसे मैं ढूंढ रहा हूं। – 5gon12eder
लेकिन कैसे आप लाइब्रेरी के साथ केवल कंपाइलर समर्थन के बिना प्रकार का नाम प्राप्त कर रहे हैं? इसके अलावा कई मददगार हैं जिन्हें टाइप_ट्रेट्स में कंपाइलर जादू की आवश्यकता होती है। परीक्षा 'is_class/enum/union' के लिए। –