2016-03-10 13 views
5

मैं कैसे कुछ करने के लिए पर उदाहरण के लिए देख रहा है और इस देखा दो वेरिएंट किया गया था:"std :: string const & s" और "const std :: string & s" के बीच क्या अंतर है?

std::string const &s; 
const std::string &s; 
अलग स्निपेट में

। यदि आपका जवाब :)

+6

कोई अंतर नहीं है, अर्थात्। सिर्फ एक सवाल है कि कौन सी शैली पसंद करती है। –

+1

पहले में एक स्थिर स्ट्रिंग का संदर्भ है। दूसरे में 'एक स्ट्रिंग का संदर्भ है जो निरंतर है। अर्थात। दोनों वास्तव में वही हैं। –

+3

संबंधित विषय: http://stackoverflow.com/questions/5503352/const-before-or-const-after http://stackoverflow.com/questions/1143262/what-is-the-difference-between-const-int -const-int-const-and-int-const – dragosht

उत्तर

5

के लिए

THX तकनीकी तौर पर यह एक ही है और कोई फर्क नहीं पड़ता। लेकिन कुछ डिबगर्स (निश्चित रूप से lldb) में आप std::string const& देखेंगे, भले ही आपने const std::string& के रूप में लिखा हो।

2

बस अन्य लोगों assertations साबित करने के लिए (मैं समझता हूँ कि RTTI constness या voltilness .name() उत्पादन पर ध्यान नहीं देता)

इस परीक्षण कार्यक्रम:

#include "stdafx.h" 
#include <string> 
#include <iostream> 

using std::string; 
using std::cout; 
using std::cin; 

    using std::endl; 

    int _tmain(int argc, _TCHAR* argv[]) 
    { 
    std::string t = "BLABLA" ; 
    std::string t1 = "BLABLA" ; 
    std::string const &s = t; 
    const std::string &d = t1; 


if (typeid(d) == typeid(s)) 
    cout << "d and s are the same type according to the rtti" << endl; 

else 
    cout << "d and s are the NOT the same type according to the rtti" << endl; 
    // here the raw output is exactly the same for both 
    cout << typeid(d).raw_name() << endl << typeid(s).raw_name() << endl; 

    cin >> t; 
    return 0; 
} 
जीसीसी के लिए

दोनों (4.9.2) (उचित संशोधन के साथ) msdn (vs2010) दोनों के लिए "एक ही प्रकार" देता है।

मैं इस "उत्तर" को योगदान के रूप में उद्देश्य देता हूं, न कि "उत्तर" के रूप में।

संपादित करें: स्कॉट-मेयर्स के "प्रभावी आधुनिक सी ++" में आइटम 4 पढ़ना मेरे द्वारा लिखे गए उदाहरण के बारे में कुछ वाकई दिलचस्प छिपी जानकारी साझा करता है। संक्षेप में, टाइपिड विश्वसनीय परिणाम नहीं देता है क्योंकि हम मूल्य द्वारा परिवर्तनीय नाम पास कर रहे हैं। जब हम एक विधि को मूल्य के आधार पर एक चर पारित कर रहे हैं, तो प्रयुक्त प्रकार इसकी स्थिरता और अस्थिरता और संदर्भ को खो देता है (भगवान के प्यार के लिए सीवीआर को छोटा कर दिया जाएगा)। यही कारण है कि उपरोक्त उदाहरण साबित नहीं करता है कि दो प्रकार के बीच अंतर है या नहीं।

वही आइटम बताता है कि बूस्ट प्रोजेक्ट टाइपइंडेक्स नामक लाइब्रेरी होस्ट करता है, जो सीवीआर गुणों को संरक्षित करता है।

+0

डाउनवॉटर, मुझे बताओ क्यों! – Aviv

+2

डाउनवॉटर - मुझे वह जगह मिली जहां मुझे गलती हुई थी, आपको बहुत धन्यवाद नहीं था। – Aviv

5

std::string const &const std::string & के बराबर है।

const std::string & स्ट्रॉस्ट्रप के सी ++ प्रोग्रामिंग भाषा में अपनाया गया शैली है और शायद "पारंपरिक शैली" है।

std::string const & विकल्प की तुलना में अधिक अनुरूप होना कर सकते हैं:

स्थिरांक-ऑन-दायें शैली हमेशा यह क्या constifies के दाईं तरफ डालता const, अन्य शैली कभी कभी पर डालता है, जबकि const बाएं और कभी-कभी दाईं ओर।

कॉन्स्ट-ऑन-द-दाएं शैली के साथ, एक स्थानीय चर जो कि कॉन्स्ट है, को दाईं ओर स्थित कक्ष के साथ परिभाषित किया गया है: int const a = 42;। इसी प्रकार एक स्थैतिक चर जो कि कॉन्स्ट है को static double const x = 3.14; के रूप में परिभाषित किया गया है। मूल रूप से प्रत्येक const उस चीज के दाईं ओर समाप्त होता है, जिसमें const शामिल है जो दाएं होने की आवश्यकता है: एक कॉन्स्ट सदस्य फ़ंक्शन के साथ।

(अधिक जानकारी के लिए What do “X const& x” and “X const* p” mean? देखें)।

आप स्थिरांक-ऑन-दायें शैली का उपयोग करने का निर्णय लेते हैं, अतर्कसंगत std::string & const s के रूप में ग़लत तरीके से लिखते std::string const &s नहीं करना सुनिश्चित करें:

ऊपर घोषणा का अर्थ है: "s एक करने के लिए एक const संदर्भ है std::string "। यह अनावश्यक है क्योंकि संदर्भ हमेशा const होते हैं (आप किसी भिन्न ऑब्जेक्ट को संदर्भित करने के लिए संदर्भ को कभी भी रीसेट नहीं कर सकते हैं)।

1

जैसा कि बताया गया है, वे वही प्रकार हैं। दाईं ओर const को पसंद करने का एक कारण यह है कि यह टेम्पलेट्स के साथ कैसे खेलता है। अधिकांश लोग केवल प्रतिस्थापन द्वारा फ़ंक्शन टेम्पलेट्स को संसाधित करते हैं। उदाहरण के लिए:

template <class T> void foo(const T& arg); 

int* p; 
foo(p); 

arg के प्रकार क्या है? आप const int*& कहना चाहते हैं, जो कि const int पर पॉइंटर का संदर्भ है, लेकिन यह गलत है। पाठ प्रतिस्थापन आपको असफल रहा है। आप

template <class T> void foo(T const& arg); 

तरह के बजाय यह लिखा गया है, तो फिर साधारण पाठ प्रतिस्थापन पैदावार सही प्रकार: int* const&। यही है, const सूचक का संदर्भ int पर।

0

जैसा बैरी ने in his answer पुराना सी वाक्यविन्यास (और उस वाक्यविन्यास का सी ++ एक्सटेंशन) गणित के रूप में पाठ प्रतिस्थापन के वैचारिक दृश्य का समर्थन नहीं करता है।

सी वाक्य रचना का उपयोग करते हुए सीधे यह इसलिए आम तौर पर एक अच्छा विचार T const, नहीं const T लिखने के लिए है, तब भी जब T एक सरल प्रकार इन प्रकार के भाव बराबर हैं, हालांकि। T const लेखन char const* const p; जैसे बहु-स्तर सूचक सूचक में असंगतता से बचाता है, जहां अंतिम const स्थानांतरित नहीं किया जा सकता है। जो उदाहरण देता है कि समानता केवल घोषणा के आरंभ में आधार प्रकार के लिए है।

कुछ महीने पहले मैंने const T लिखने का प्रयोग शुरू किया था, और उस नोटेशन लगातार का उपयोग कर शुरू किया था। चूंकि अब मैक्रोज़ का उपयोग किए बिना सी ++ 11 के बाद यह संभव है। स्थिरता का उपयोग मैं नामित प्रकार बिल्डरों

तरह
template< class Some_type > 
using Ptr_ = Some_type*; 

तो

char const* const p = something; 

कि बजाय पढ़ा-से-दाएँ-से-बाएँ की मैं और साधारण पढ़ने की दिशा में लिख सकता हूँ कर सकते हैं का समर्थन करने के

const Ptr_<const char> p = something; 

यह थोड़ा और वर्बोज़ है, लेकिन अब मैं इसका उपयोग कर कुछ अनुभव के साथ सोचता हूं कि यह इसके लायक है (मुझे इसके बारे में निश्चित नहीं था, यह एक प्रयोग था NT)।

मुख्य दोष यह है कि यह नोटेशन सी वाक्यविन्यास के प्रत्यक्ष उपयोग की तरह (फ़ंक्शन टेम्पलेट) फ़ंक्शन तर्कों के लिए प्रकार की कटौती का समर्थन करता है, यह auto घोषणाओं के लिए प्रकार की कटौती का समर्थन नहीं करता है। खुशी से, चूंकि एक प्रारंभकर्ता आसानी से const बनाया जा सकता है, केवल समस्याग्रस्त मामला सरणी के संदर्भ में है।मेरे व्यावहारिक समाधान अब तक ऐसे मामलों में सी (या बल्कि, सी ++) वाक्यविन्यास का उपयोग करने के लिए किया गया है, लेकिन मुझे लगता है कि यह भाषा में कमी या छेद का प्रतिनिधित्व करता है, संभवतः कुछ सामान्य समाधान के साथ जो चीजों को और अधिक आसान बना देता है अन्य संदर्भ

मेरे वर्तमान प्रकार के बिल्डरों के लिए Ptr_, the cppx/core_language_support/type_builders.hpp file at Github देखें। उनमें शामिल हैं उदा। फ़ंक्शन तर्कों के लिए In_। और हां, मैंने पाया है कि स्पष्टता में, कुछ verbosity के बावजूद, यह इरादा बहुत स्पष्ट बनाता है। हालांकि, सीपीएक्स सामान प्रयोगात्मक है और परिवर्तन के अधीन है। यहां से जुड़ी विशिष्ट फ़ाइल को भी स्थानांतरित किया जा सकता है, लेकिन यह वहां होगा। :)

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