简体   繁体   English

checked_array_iterator <T> 在C ++ 11中

[英]checked_array_iterator<T> in C++11

C++11 provides std::array<T> to wrap C arrays, but only where you know the array size at compile time. C ++ 11提供了std::array<T>来包装C数组,但只有在编译时知道数组大小的地方。 What is the best way of handling arrays whose size is only known at runtime? 处理大小仅在运行时已知的数组的最佳方法是什么?

Background 背景

I'm porting some code from MSVC to GCC. 我正在将一些代码从MSVC移植到GCC。 MSVC provides the stdext::checked_array_iterator<T> template to provide some protection for lines of code such as this: MSVC提供了stdext::checked_array_iterator<T>模板,为代码行提供了一些保护,例如:

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

So far I can think of two options: abandoning the safety check or writing my own implementation. 到目前为止,我可以想到两个选择:放弃安全检查或编写我自己的实现。 On that note, I'd 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;
    };
}

Would this be so bad? 这会不会这么糟糕?

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

It's more efficient too, because it checks just once that the size is OK, rather than once per element. 它也更有效,因为它只检查一次大小是否正常,而不是每个元素一次。

In some cases, you could use Eigen Map (or write a similar implementation). 在某些情况下,您可以使用Eigen Map (或编写类似的实现)。 It is essentially a vector which does not manage its own storage but gets pointer and size in its constructor. 它本质上是一个向量,它不管理自己的存储,但在构造函数中获取指针和大小。 In that regard, it is quite similar to the level of safety provided by stdext::checked_array_iterator<T> . 在这方面,它与stdext::checked_array_iterator<T>提供的安全级别非常相似。 On the other hand, it is not meant to be an iterator, it is meant to be a matrix (or vector as a special case) class. 另一方面,它并不意味着是一个迭代器,它意味着是一个矩阵(或矢量作为特例)类。 Ane Eigen is both free and multi-platform. Ane Eigen既是免费的,也是多平台的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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