Checked_array_iterator <T> in C ++ 11

C ++ 11 provides std::array<T>

C for wrapping arrays, but only where you know the size of the array at compile time. What's the best way to handle arrays whose size is only known at runtime?

Background

I am porting some code from MSVC to GCC. MSVC provides a template stdext::checked_array_iterator<T>

to provide some protection for lines of code, for example:

std::copy(v.begin(), v.end(), stdext::checked_array_iterator<int*>(arr, numVals));

      

So far, I can think of two options: opt out of security checks or write my own implementation. In this post, I would be grateful for any constructive comments on this implementation:

namespace stdext {
    template<typename T>
    struct checked_array_iterator
    {
    private:
        T _val;
        size_t _len;
    public:
        typedef typename std::remove_pointer<T>::type value_type;
        checked_array_iterator(T val, size_t len) : _val(val), _len(len) {}
        checked_array_iterator<T> operator++(int)
        {
            if(_len == 0)
                throw std::range_error("Array iterator overrun");
            checked_array_iterator<T> retval = *this;
            _val++;
            _len--;
            return retval;
        }
        checked_array_iterator<T> & operator++()
        {
            if(_len == 0)
                throw std::range_error("Array iterator overrun");
            _val++;
            _len--;
            return *this;
        }
        value_type & operator*()
        {
            return *_val;
        }
        bool operator==(checked_array_iterator<T>& other) { return other._val == _val; }
        bool operator!=(checked_array_iterator<T>& other) { return !(other == *this); }
        T operator->() { return _val; }
    };
}
namespace std
{
    template <typename T>
    struct iterator_traits<stdext::checked_array_iterator<T>>
    {
        typedef std::ptrdiff_t difference_type;
        typedef typename std::remove_pointer<T>::type value_type;
        typedef T pointer;
        typedef value_type& reference;
        typedef std::input_iterator_tag iterator_category;
    };
}

      

+3


source to share


2 answers


Is it really that bad?

if (v.size() > numVals)
  throw std::runtime_error("oops");
std::copy(v.begin(), v.end(), arr);

      



This is more efficient because it only checks once that the size is ok, not once per item.

0


source


In some cases, you can use Eigen Map (or write a similar implementation). It is essentially a vector that does not manage its own storage, but receives a pointer and size in its constructor. In this respect, it is very similar to the level of security provided stdext::checked_array_iterator<T>

. On the other hand, it shouldn't be an iterator, it should be a class (or vector as a special case). Ane Eigen is free and multi-platform.



0


source







All Articles