我可以这样遍历 C 风格的数组:
char foo[3] = { 'a', 'b', 'c' };
for (auto it = std::begin(foo); it != std::end(foo); ++it)
{
*it = 'k'; //values of foo are correctly modified
}
现在假设我想将数组包装在一个类中,并公开返回相关迭代器的 begin()
和 end()
方法。
我尝试了以下方法:
template<size_t size>
class StackMemPolicy
{
private:
char mem[size];
public:
typedef typename std::iterator<std::input_iterator_tag, char> iter;
iter begin()
{
return std::begin(mem);
}
iter end()
{
return std::end(mem);
}
}
返回的类型声明似乎是错误的,下面的调用代码无法编译:
StackMemPolicy<4> bar;
for (auto it = bar.begin(); it != bar.end(); ++it)
{
*it = 'k';
}
错误如下:
Error 1 error C2678: binary '!=' : no operator found which takes a left-hand operand of type 'StackMemPolicy<4>::iter' (or there is no acceptable conversion)
谁能告诉我哪里出错了?
最佳答案
std::iterator
旨在用作基类。来自 24.4.2/1:
namespace std {
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator {
typedef T value_type;
typedef Distance difference_type;
typedef Pointer pointer;
typedef Reference reference;
typedef Category iterator_category;
};
}
它只会给你 some typedefs并且不会神奇地实现所有必需的运算符。在你的例子中,begin()
和 end()
应该只返回 char*
,already has specializations对于 std::iterator_traits
。
但是,如果您的迭代器必须更智能(例如,这可能是某种循环缓冲区),您将必须创建自己的迭代器类并实现所需的运算符。为了让迭代器与标准库中的各种功能(例如 std::iterator_traits
)一起工作,您需要预定义的类型定义,例如 value_type
、iterator_category
等
由于有时很难获得这些权利,std::iterator
将根据给定的模板参数为您定义这些。这是 using std::iterator_traits
with an iterator 的示例.
请注意,自 C++17 起,std::iterator
已被弃用 various reasons . This post有一些解决方法。
关于c++ - 将迭代器返回到 C 数组的方法的正确类型声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30577245/