简体   繁体   中英

Calling member functions on const iterators

I've got two classes, one Measurement class which contains a vector<double> and an Experiment which contains a vector<Measurement> :

class Measurement {

private:
    vector<double> dataSet;
    string time_stamp;  

public:
    const vector<double>& getDataSet() {return dataSet;}
    string getTimeStamp() {return time_stamp;}

};

class Experiment {

private: 
    vector<Measurement> measurements;

public:
    const vector<Measurement>& getMeasurements() {return measurements;}

};

In short, I am trying to iterate through each Measurement in an Experiment (outer loop), and then through the data in each Measurement (inner loop).

I found some help at this thread , which is why the member functions getDataSet() and getMeasurements() are const & (to make the iterators compatible).

However when I try to call iter_meas->getDataSet() , I run into trouble.

int main() {


Experiment expTest(); // experiment already filled with measurements

vector<Measurement>::const_iterator iter_meas;
vector<double>::const_iterator iter_data;

for (iter_meas = expTest.getMeasurements().begin(); iter_meas != expTest.getMeasurements().end(); iter_meas++) {

    cout << iter_meas->getTimeStamp() << ',';   //this works fine :)

    for (iter_data = iter_meas->getDataSet().begin(); iter_data != iter_meas->getDataSet().end(); iter_data++){
        //              ^^^ here I get the error
        //              "the object has qualifiers that are not compatible with the member function getDataSet"
        //              "object type is const measurement"          
        cout << iter_data << ",";
    }
    cout << '\n';
}
return 0;
}

I understand that iter_meas represents a const Measurement , but I'm not sure why I can't called Measurement:: member functions on it?

I'm using Visual Studio Community 2015.

It means that the function returns const value, nothing more.

const int foo();

If the variable is const, it can't change value, it only can be initialized.

So if you have const iterator in your program, it can't change value of your object. With the methods is the same situation, it can't call methods that may change the value.

There is a solution. You have to declare your function as const (not returning const value)

int foo() const;

Now you can call this function from const iterator. Declare it as:

const vector<Measurement>& getMeasurements() const {return measurements;}
const vector<double>& getDataSet() const {return dataSet;} // same problem

The const_iterator iter_meas represents a reference to a constant value ( const Measurement& ) and prevents modification of the referenced value. This particularly means that you cannot call non-static methods on such a value if the method itself is not declared as const . Such a const -declaration expresses that the method will not alter it's object.

In your code, you call iter_meas->getDataSet() , where this non-static method is declared as const vector<double>& getDataSet() , ie not as const which would be declared as const vector<double>& getDataSet() const . Note the const at the end of the declaration.

So with the following changes, this issue should be solved:

const vector<double>& getDataSet() const {return dataSet;}
string getTimeStamp() const {return time_stamp;}

The method getDataSet is not marked const. Since you have the method returning a const reference to the vector the method itself needs to be const, ie disallow mutation of the vector. So, your method should be declared as:

const vector<double>& getDataSet() const;

Same for getMeasurements. Also, if you're using C++ 11, maybe you'd like to use the range based for loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM