【发布时间】:2013-06-02 19:53:10
【问题描述】:
我正在编写一个库来读取一些特定的文件格式。正在使用内存映射文件(boost::interprocess 模板)读取该文件。在这些文件上,我必须使用std::regex 进行一些搜索。为了避免不必要的复制,我想直接使用内存映射文件(作为 C 风格的 char 数组)。
经过一段时间的研究,我想出了以下两种方法:
- 使用
streambuf对象的pubsetbuf方法 - 使用
char*指针作为迭代器
但由于第一种方法的实现对于 STL 供应商来说是可选的,所以我坚持使用第二种方法。由于std::string::iterator 的构造函数被声明为私有,并且整个迭代器实现似乎也是特定于供应商的。我写了自己的迭代器:
template<typename T>
class PointerIterator: std::iterator<std::input_iterator_tag, T> {
public:
PointerIterator(T* first, std::size_t count): first_(first), last_(first + count) {}
PointerIterator(T* first, T* last): first_(first), last_(last) {}
class iterator {
public:
iterator(T* p): ptr_(p) {}
iterator(const iterator& it): ptr_(it.ptr_) {}
iterator& operator++() {
++ptr_;
return *this;
}
iterator operator++(int) {
iterator temp(*this);
++ptr_;
return temp;
}
bool operator==(const iterator& it) { return ptr_ == it.ptr_; }
bool operator!=(const iterator& it) { return ptr_ != it.ptr_; }
T& operator*() { return *ptr_; }
private:
T* ptr_;
};
iterator begin() {
return iterator(first_);
}
iterator end() {
return iterator(last_);
}
private:
T* first_;
T* last_;
};
迭代器正在工作,但要与 std::regex_search 方法(或其他与字符相关的 STL 方法)一起使用,它必须与 STL 迭代器的类型相同。
是否有一些通用的方法可以将我的迭代器转换为 STL 迭代器(可移植于 STL 实现)或使用我没有提到的另一种方法来实现整个 thng?
编辑:
来源使用std::regex_search:
std::regex re(...);
boost::interprocess::mapped_region region(...);
char* first = static_cast<char*>(region.get_address());
char* last = first + 5000;
// ...
PointerIterator<char> wrapper(first, last);
std::smatch match;
while (std::regex_search(wrapper.begin(), wrapper.end(), match, re)) { // Error: No matching function call to 'regex_search'
// do something
}
谢谢
【问题讨论】:
-
"但是要与 std::regex_search 方法一起使用 [...] 它必须与 STL 迭代器的类型相同" 您能详细说明一下吗?标准库函数大多是generic,接受满足迭代器要求的任何类型。此外,还有一个
regex_searchoverload 接受char const*(作为干草堆)。 -
为什么不能直接使用
char*指针作为迭代器? -
@DyP 我正要问同样的事情。由于指针满足双向迭代器的要求,所以问题必须出在
regex_search的使用上,并且似乎没有必要将它们包装在一个交互器类中。 -
@DyP 文件中的字符串不是以零结尾的,我无法在不复制字符串的情况下添加“\0”。 regex_search 的问题是没有重载版本接受我的迭代器,而且我没有运气在我的 STL 实现中找到正确的类型(LLVM Compiler 4.2 在 OS X 上随 Xcode 一起提供)
-
您不需要将指针包装在一个类中,因为指针满足
std::regex_search的所有迭代器要求。只需将您的第一个和最后一个指针作为begin和end参数传递。