[英]checked_array_iterator<T> in C++11
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);
它也更有效,因为它只检查一次大小是否正常,而不是每个元素一次。
在某些情况下,您可以使用Eigen Map (或编写类似的实现)。 它本质上是一个向量,它不管理自己的存储,但在构造函数中获取指针和大小。 在这方面,它与stdext::checked_array_iterator<T>
提供的安全级别非常相似。 另一方面,它并不意味着是一个迭代器,它意味着是一个矩阵(或矢量作为特例)类。 Ane Eigen既是免费的,也是多平台的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.