我目前有以下函数来读取数组或原始数据的向量(_readStream
是一个std::ifstream
):
template<typename IteratorType>
inline bool MyClass::readRawData(
const IteratorType& first,
const IteratorType& last,
typename std::iterator_traits<IteratorType>::iterator_category* = nullptr
)
{
_readStream.read(reinterpret_cast<char*>(&*first), (last-first)*sizeof(*first));
return _readStream.good();
}
第一个问题:这个功能对你来说似乎还可以吗?
当我们直接读取内存块时,仅当从 first
到 last
的内存块在内存中是连续的时,它才会起作用。如何检查?
撇开示例函数不谈,如果不检查两者之间每个元素的地址,您永远无法完全确定迭代器将形成一个连续的内存。
但是,合理的健全性测试是检查两者之间的内存区域是否与两者之间的计数相同:
assert(&*last - &*first == last - first &&
"Iterators must represent a contiguous memory region");
n4183 是一篇关于添加连续迭代器特征的想法的论文。 目前正在考虑C++1z(希望是C++17)。
在它下面,您可以执行std::is_contiguous_iterator<It>::value
并获取It
是否是连续迭代器。 (这将需要迭代器设计者的支持)。
typename std::iterator_traits<IteratorType>::iterator_category* = nullptr
这是无用的,因为std::iterator_traits
有一个主模板,其中包含未连接定义的成员类型 iterator_category
。默认模板参数是一个迭代器,如果不是,则它是前提条件冲突 - 因此,您不会得到 SFINAE,但如果尝试上述无效实例化,则会出现硬错误。
当我们直接读取内存块时,仅当从第一个到最后一个的内存块在内存中是连续的时,它才会起作用。如何检查?
我不知道你会对"内存中的连续"概念提出什么确切的要求。但是,您是否考虑过以下几点?
template<typename T>
bool readRawData(T* first, T* last);
前提是[ first, last )
是数组中的有效指针作为迭代器范围。
如果你想对T
提出进一步的要求(例如,由于你使用了read
而变得微不足道的可复制性),你也可以表达/记录这些要求。