Note that there are some explanatory texts on larger screens.

plurals
  1. POWrong version of overridden [] operator called in class
    primarykey
    data
    text
    <p>I have a simple two-dimensional line class which holds two vectors of doubles. I have added getValue and setValue functions, but would prefer the public interface to have the square bracket operator available alongside these functions. The following code shows the implementation and use:</p> <pre><code>#include &lt;vector&gt; #include &lt;algorithm&gt; #include &lt;cassert&gt; class Simple2DLine { public: Simple2DLine(); // Simple read method with linear interpolation double getValue(double x) const; // Simple write method, adds a curve point, keeping the arrays sorted void setValue(double x, double y); double&amp; operator [](double x); const double operator [](double x) const; private: std::vector&lt;double&gt; m_X; std::vector&lt;double&gt; m_Y; int getNearestIndex(double x) const; }; Simple2DLine::Simple2DLine() { } void Simple2DLine::setValue(double x, double y) { // Get the index of the point at or just before 'x' int idx = getNearestIndex(x); // Check if the exact point already exists. if (idx &gt;= 0) { if (m_X[idx] == x) { m_Y[idx] = y; return; } else { // Insert adds the value just BEFORE idx, so increment it before inserting. ++idx; m_X.insert(m_X.begin() + idx,x); m_Y.insert(m_Y.begin() + idx,y); return; } } // Otherwise, just insert at the front. m_X.insert(m_X.begin(),x); m_Y.insert(m_Y.begin(),y); } double Simple2DLine::getValue(double x) const { // Make sure there are points - if not, return 0. if (m_X.size() == 0) { return 0; } // Make sure it's not out of bounds. if (x &lt; m_X.front() || x &gt; m_X.back()) { return 0; } // Check if it's at or after the last point if (x == m_X.back()) { return m_X.back(); } // Find the point just before the given point. int idx = getNearestIndex(x); // Check if we're on the exact point if (m_X[idx] == x) { return m_X[idx]; } else { // Find the distance from the nearest point and linearly interpolate. double dist = x - m_X[idx]; return m_Y[idx] + dist * (m_Y[idx + 1] - m_Y[idx]) / (m_X[idx + 1] - m_X[idx]); } } double&amp; Simple2DLine::operator [](double x) { // Create a space for the new value setValue(x,0.0); int idx = getNearestIndex(x); return m_Y[idx]; } const double Simple2DLine::operator [](double x) const { return getValue(x); } // Returns the index of the point at or just before 'x'. Invalid values return -1. int Simple2DLine::getNearestIndex(double x) const { if (m_X.empty()) { return -1; } std::vector&lt;double&gt;::const_iterator xBegin(m_X.begin()); std::vector&lt;double&gt;::const_iterator xEnd(m_X.end()); // Get an iterator to the first value GREATER than our search value std::vector&lt;double&gt;::const_iterator it = upper_bound(xBegin,xEnd,x); // If the iterator is at the beginning, all values are greater if (it == xBegin) { return -1; } // Otherwise, decrement the iterator by 1, and return its' distance from the start. return (it - 1) - xBegin; } int main(int argc, char** argv) { Simple2DLine tda; tda.setValue(0.0,10.0); tda.setValue(1.0,15.0); tda.setValue(2.0,20.0); tda.setValue(3.0,25.0); double tmp = tda.getValue(0.5); assert(abs(tmp - 12.5) &lt; 0.000001); tmp = tda.getValue(1.5); assert(abs(tmp - 17.5) &lt; 0.000001); tmp = tda.getValue(2.5); assert(abs(tmp - 22.5) &lt; 0.000001); // Here, the wrong version of the overridden operator is being called. tmp = tda[1.5]; tda[2.5] = 22.5; } </code></pre> <p>When I access the line object in the following fashion, the correct version of the operator is called (non-const)</p> <pre><code>tda[2.5] = 22.5; </code></pre> <p>However, when I try to use the const version, as follows:</p> <pre><code>tmp = tda[1.5]; </code></pre> <p>the non-const version is called. Is there an error in my implementation? Or is it not possible to access the class in this fashion?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload