c++ - त्रुटि: xxx डिस्क्वार्ड क्वालिफायर के 'यह' तर्क के रूप में XXX पास करना


#include <iostream>
#include <set>

using namespace std;

class StudentT {

public:
    int id;
    string name;
public:
    StudentT(int _id, string _name) : id(_id), name(_name) {
    }
    int getId() {
        return id;
    }
    string getName() {
        return name;
    }
};

inline bool operator< (StudentT s1, StudentT s2) {
    return  s1.getId() < s2.getId();
}

int main() {

    set<StudentT> st;
    StudentT s1(0, "Tom");
    StudentT s2(1, "Tim");
    st.insert(s1);
    st.insert(s2);
    set<StudentT> :: iterator itr;
    for (itr = st.begin(); itr != st.end(); itr++) {
        cout << itr->getId() << " " << itr->getName() << endl;
    }
    return 0;
}

पंक्ति में:

cout << itr->getId() << " " << itr->getName() << endl;

यह एक त्रुटि देता है कि:

../main.cpp:35: त्रुटि: 'कॉन्स्ट स्टूडेंट टी' को 'इस विद्यार्थी' के उत्तराधिकारी के रूप में उत्तीर्ण करना :: getId () 'क्वालिफायर डिस्कार्ड करता है

../main.cpp:35: त्रुटि: 'std :: string studentt :: getName ()' के 'यह' तर्क के रूप में 'const studentt' को गुजारें

इस कोड में क्या गलत है? धन्यवाद!



Answers


std::set में ऑब्जेक्ट const StudentT रूप में संग्रहीत हैं इसलिए जब आप const ऑब्जेक्ट के साथ getId() कॉल करने का प्रयास करते हैं तो कंपाइलर एक समस्या का पता लगाता है, अर्थात् आप const ऑब्जेक्ट पर एक गैर-कॉन्स्ट सदस्य फ़ंक्शन कॉल कर रहे हैं, जिसे अनुमति नहीं है क्योंकि गैर-कॉन्स्ट सदस्य कार्य नहीं करता है, इसे संशोधित नहीं करने के लिए वस्तु; इसलिए संकलक एक सुरक्षित धारणा बनाने जा रहा है जो getId() ऑब्जेक्ट को संशोधित करने का प्रयास कर सकता है लेकिन साथ ही, यह भी नोटिस करता है कि ऑब्जेक्ट को कॉन्स्ट किया गया है; इसलिए const ऑब्जेक्ट को संशोधित करने का कोई भी प्रयास एक त्रुटि होना चाहिए। इसलिए संकलक त्रुटि संदेश उत्पन्न करता है।

इसका समाधान सरल है: फ़ंक्शंस कन्वर्स को बनाओ:

int getId() const {
    return id;
}
string getName() const {
    return name;
}

यह आवश्यक है क्योंकि अब आप const ऑब्जेक्ट्स पर getId() और getName() को कॉल कर सकते हैं:

void f(const StudentT & s)
{
     cout << s.getId();   //now okay, but error with your versions
     cout << s.getName(); //now okay, but error with your versions
}

एक sidenote के रूप में, आप operator<

inline bool operator< (const StudentT & s1, const StudentT & s2)
{
    return  s1.getId() < s2.getId();
}

नोट पैरामीटर अब const संदर्भ हैं।




सदस्य कार्य जो क्लास इंस्टेंस को संशोधित नहीं करते हैं उन्हें const रूप में घोषित किया जाना चाहिए:

int getId() const {
    return id;
}
string getName() const {
    return name;
}

कभी भी आप "क्वालिफायर डिस्क्वाइज़र" देखते हैं, यह const या volatile बारे में बात कर रहा है




असल में सी ++ मानक (यानी सी ++ 0x ड्राफ्ट ) (मेरे पास बताए जाने के लिए @ एक्सो और @ बेन वोट के लिए टीएनएक्स) कहते हैं:

23.2.4 एसोसिएटेड कंटेनर
5 सेट के लिए और बहुस्तरीय मूल्य प्रकार कुंजी प्रकार के समान है। मानचित्र के लिए और बहुमूल्य यह जोड़ी के बराबर है। एक सहकारी कंटेनर में चाबियाँ अपरिवर्तनीय हैं
एक एसोसिएटिव कंटेनर के 6 द्वार द्विदिश इटरेटर श्रेणी का है। एसोसिएटिव कंटेनरों के लिए जहां मूल्य का प्रकार कुंजी प्रकार के समान होता है, दोनों हीटर और const_iterator स्थिर पुनरावर्तक होते हैं। यह अनिर्दिष्ट है कि यातायात और const_iterator समान प्रकार हैं या नहीं।

इसलिए वीसी ++ 2008 डिंकुमावेयर का कार्यान्वयन दोषपूर्ण है।

पुराना उत्तर:

आपको यह त्रुटि मिली क्योंकि std lib के कुछ कार्यान्वयन में set::iterator set::const_iterator

उदाहरण के लिए, libstdc ++ (जी ++ के साथ भेज दिया गया) इसमें है (संपूर्ण स्रोत कोड के लिए यहां देखें):

typedef typename _Rep_type::const_iterator            iterator;
typedef typename _Rep_type::const_iterator            const_iterator;

और एसजीआई के दस्तावेज़ में यह कहा गया है:

iterator       Container  Iterator used to iterate through a set.
const_iterator Container  Const iterator used to iterate through a set. (Iterator and const_iterator are the same type.)

दूसरी ओर, वीसी ++ 2008 एक्सप्रेस आपके कोड को बिना शिकायत के संकलित करता है कि आप set::iterator एस पर गैर कॉन्स्ट विधियों को कॉल कर रहे हैं।










Tags