2015-12-21 17 views
6

लाइब्रेरी बुनियादी बातों के लिए सी ++ एक्सटेंशन, संस्करण 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 चेक किया है लेकिन अभी तक कुछ भी नहीं मिला है।

+7

संकलक जादू, प्रति 'std :: के रूप में –

+0

@RichardHodges type_info'' typeid' एक काफी सीधी-सपाट समारोह के रूप में लागू किया जा सकता। गैर-पॉलीमोर्फिक प्रकारों के लिए, संकलक पहले से ही जानता है कि उत्तर पॉलिओर्फिक प्रकारों के लिए सीधे स्ट्रिंग अक्षर को सम्मिलित कर सकता है, इसे रन-टाइम पर 'vptr' का पालन करने के लिए सरल कोड उत्पन्न करना होगा। मैं नहीं देखता कि कैसे 'source_location' लागू करने के लिए समान रूप से सरल होगा। लेकिन अगर आप जानते हैं, तो यह वही जवाब है जिसे मैं ढूंढ रहा हूं। – 5gon12eder

+0

लेकिन कैसे आप लाइब्रेरी के साथ केवल कंपाइलर समर्थन के बिना प्रकार का नाम प्राप्त कर रहे हैं? इसके अलावा कई मददगार हैं जिन्हें टाइप_ट्रेट्स में कंपाइलर जादू की आवश्यकता होती है। परीक्षा 'is_class/enum/union' के लिए। –

उत्तर

6

इसे कार्यान्वित करने के लिए कंपाइलर से समर्थन की आवश्यकता होगी। उदाहरण के लिए, with gcc के लिए, आप संभवतः इस्तेमाल कर सकते हैं इस समारोह built-ins functions

तरह
int __builtin_LINE() 

पूर्वप्रक्रमक __LINE__ मैक्रो के बराबर है और बिल्ट-इन के आह्वान की लाइन संख्या दिखाता है। एक समारोह F के लिए एक सी ++ डिफ़ॉल्ट तर्क में, यह F करने के लिए कॉल की लाइन नंबर हो जाता है।

const char * __builtin_FUNCTION() 

इस समारोह पूर्वप्रक्रमक __FUNCTION__ मैक्रो के बराबर है और समारोह नाम रिटर्न में निर्मित के आह्वान में है।

const char * __builtin_FILE() 

इस समारोह पूर्वप्रक्रमक के बराबर है __FILE__ स्थूल और फ़ाइल नाम लौटाता है अंतर्निहित का आविष्कार अंदर है। एक फंक्शन F के लिए एक सी ++ डिफ़ॉल्ट तर्क में, यह कॉल का फ़ाइल नाम F पर मिलता है।

+0

कूल, यह वही तरह की विशेषताएं है जिन्हें मैं ढूंढ रहा हूं। मुझे नहीं पता था कि वे पहले ही जीसीसी में लागू किए गए थे। विशेष रूप से डिफ़ॉल्ट-तर्कों के लिए अर्थशास्त्र उल्लेखनीय हैं (और वास्तव में 'स्रोत_स्थान' की आवश्यकता क्या है)। ऐसा लगता है कि libstdC++ बिना किसी अतिरिक्त जादू के दूर हो सकता है। – 5gon12eder

+0

ठीक है, लिंक किए गए ई-मेल में उल्लिखित सीमाओं को छोड़कर ... – 5gon12eder

+0

@ 5gon12eder दाएं, [बगजिला लिंक] (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66561) ईमेल श्रृंखला में मौजूदा बिल्ट-इन्स का उपयोग करने के लिए कुछ सीमाओं का उल्लेख करता है लेकिन मैं अनुमान लगा रहा हूं कि अंतिम कार्यान्वयन कुछ समान समान होगा। – Praetorian

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