When implementing the [] operator, how do I enable border checking?

First of all, I apologize for the lengthy approach to such a simplified question.

I implement a class that serves as a very long 1-dimensional index on a space filling curve or an n-tuple representing the Cartesian coordinate to which the index corresponds.

class curvePoint
{
public:
    friend class curveCalculate;

    //Construction and Destruction
    curvePoint(): point(NULL), dimensions(0) {}
    virtual ~curvePoint(){if(point!=NULL) delete[] point;}

    //Mutators
    void convertToIndex(){ if(isTuple()) calc(this); }
    void convertToTuple(){ if(isIndex()) calc(this); }
    void setTuple(quint16 *tuple, int size);
    void setIndex(quint16 *index, int size);
    void setAlgorithm(curveType alg){algorithm = alg;}

    //Inspectors
    bool isIndex(){return current==Index;}
    bool isTuple(){return current==Tuple;}
    size_t size(){return dimensions;}
    quint16 operator[](size_t index);

    enum curveType{HilbertCurve, ZCurve, GrayCodeCurve};
    enum status{Index, Tuple};

private:
    curveCalculate calc;
    curveType algorithm;
    quint16 *point;
    size_t dimensions;
    status current;
};

(The length of the array pointed to by the dot is the dimensions)

In any case, in the implementation of the operator [], I was wondering what is the best method for checking bounds. I want to avoid exception exceptions, if at all possible, and the entire range of values โ€‹โ€‹can be used for each number in the array, so it is also impossible to return a special value for an error outside the bounds;

I was thinking of something similar, but implemented in a class definition:

quint16 curvePoint::operator[](size_t index)
{
    return point[ index % dimensions ];
}

, , , , ; , .

? , ?

: , .., , , stl .

, , , , stl , .

; , , ?

, , , , , Qt, , , .

+3
13

- , ++. , .

++ . [] , std::vector::operator[] undefined, . , std::vector::at

, , "".

+12

[] , . , , ;

:

  • . . "" , -, . : . : , , lie. 10- 1 10:

: " 3- ?"

: "".

: " 9- ?"

: "".

: " 1203- ?"

Me: (... 1,203% 10 = 3...) > "".

: ", . , ?"

:

  • : . , . - .
  • : .
+9

, . - , , .

+7

- "" , . , , - "" , .

, .

quint16 curvePoint::operator[](size_t index)
{
    if( index >= dimensions)
    {
       throw std::overflow_error();
    }
    return point[ index ];
}

, , (, ):

quint16 curvePoint::operator[](size_t index)
{
    assert( index < dimensions);
    return point[ index ];
}

, std::vector < quint16 > . , :

quint16 curvePoint::operator[](size_t index)
{
    // points is declared as std::vector< quint16> points;
    return points[ index ];
}
+3

[], , , , , , .

+2

assert.

quint16 curvePoint::operator[](size_t index)
{
    assert(index < dimensions);
    return point[index];
}

Boost, BOOST_ASSERT.

+1

# . , Qt. QVariant. QVariant , , . , :

QVariant curvePoint::operator[](size_t index){
    QVariant temp;
    if(index > dimensions){
        temp = QVariant(QVariant::Invalid);
    }
    else{
        temp = QVariant(point[index]);
    }

    return temp;
}

, , - .

std::pair<quint16, bool> curvePoint::operator[](size_t index){
    std::pair<quint16, bool> temp;
    if(index > dimensions){
        temp.second = false;
    }
    else{
        temp.second = true;
        temp.first = point[index];
    }
    return temp;
}

QPair, โ€‹โ€‹ , STL .

+1

, , stl.

std::vector : at, , operator[] - . . % size(), . , . , , .

const, const. std::vector:

reference at(size_type _Pos);
const_reference at(size_type _Pos) const;

reference operator[](size_type _Pos);
const_reference operator[](size_type _Pos) const;

, , API, , API. API, , , .

+1

" " [] ( ).

, .

0

- ,

return point[ index % dimensions ];

. , .

:

  • ( , )
  • " " (.. ). % , ( undefined undefined), "" / .

, , , . , .

, Cฤƒtฤƒlin STL, .

0

, . , , .

0

modulo - (.. point[-3] = point[dimensions - 3]). , modulo, .

0

- . :

template <class OutOfBoundsPolicy>
quint16 curvePoint::operator[](size_t index)
{
    index = OutOfBoundsPolicy(index, dimensions);
    return point[index];
}

, . :

struct NoBoundsCheck {
    size_t operator()(size_t index, size_t /* max */) {
        return index;
    }
};

struct WrapAroundIfOutOfBounds {
    size_t operator()(size_t index, size_t max) {
        return index % max;
    }
};

struct AssertIfOutOfBounds {
    size_t operator()(size_t index, size_t max) {
        assert(index < max);
        return index % max;
    }
};

struct ThrowIfOutOfBounds {
    size_t operator()(size_t index, size_t max) {
        if (index >= max) throw std::domain_error;
        return index;
    }
};

struct ClampIfOutOfBounds {
    size_t operator()(size_t index, size_t max) {
        if (index >= max) index = max - 1;
        return index;
    }
};
0

Source: https://habr.com/ru/post/1710974/


All Articles