将迭代器返回到C数组的方法的正确类型声明

Hei*_*bug 5 c++ arrays types iterator declaration

我可以这样迭代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
}
Run Code Online (Sandbox Code Playgroud)

现在假设我想包装类内部数组,暴露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);
    }
 }
Run Code Online (Sandbox Code Playgroud)

似乎返回的类型声明是错误的,并且以下调用代码不编译:

StackMemPolicy<4> bar;
for (auto it = bar.begin(); it != bar.end(); ++it)
{
    *it = 'k';
}
Run Code Online (Sandbox Code Playgroud)

错误如下:

错误1错误C2678:binary'!=':找不到运算符,它接受类型为'StackMemPolicy <4> :: iter'的左手操作数(或者没有可接受的转换)

谁能告诉我哪里是我的错误?

isa*_*nae 10

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;
  };
}
Run Code Online (Sandbox Code Playgroud)

它只给你一些typedef,并不会神奇地实现所有必需的运算符.在你的情况,begin()end()应可能只是返回char*,这已经有专长std::iterator_traits.

但是,如果您的迭代器必须更智能(例如,这可能是某种循环缓冲区),则必须创建自己的迭代器类并实现所需的运算符.对于迭代器在标准库中各种功能的工作(如std::iterator_traits),你需要预定义的typedef如value_type,iterator_category

由于获得这些权利有时会很棘手,因此std::iterator将根据给定的模板参数为您定义.这是一个使用std::iterator_traits迭代器的例子.

请注意,从C++ 17开始,std::iterator由于各种原因已被弃用.这篇文章有一些解决方法.