checked_array_iterator在<T>C++11

checked_array_iterator<T> in C++11

本文关键字:C++11 gt lt iterator checked array      更新时间:2023-10-16

C++11提供了std::array<T>来包装C数组,但仅限于在编译时知道数组大小的情况。处理只有在运行时才知道大小的数组的最佳方法是什么?

背景

我正在将一些代码从MSVC移植到GCC。MSVC提供stdext::checked_array_iterator<T>模板来为代码行提供一些保护,例如:

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

到目前为止,我可以想到两种选择:放弃安全检查或编写自己的实现。关于这一点,我将感谢对这一实施的任何建设性意见:

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;
    };
}

这会这么糟糕吗?

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

它也更高效,因为它只检查一次大小是否正常,而不是每个元素检查一次。

在某些情况下,您可以使用特征映射(或编写类似的实现)。它本质上是一个向量,它不管理自己的存储,而是在构造函数中获取指针和大小。在这方面,它与stdext::checked_array_iterator<T>提供的安全级别非常相似。另一方面,它不意味着是迭代器,它意味着是矩阵(或特殊情况下的向量)类。Ane Eigen既是自由的,也是多平台的。