个性化阅读
专注于IT技术分析

C++迭代器或包装器适配器示例

如果你想把一个可迭代范围和另一个在某种程度上转换底层迭代器,并允许循环或构造其他对象:

for (auto ch : Upper("abcdef"))
{
    // Prints "ABCDEF"
    std::cout << ch;
}
Upper up(std::string("fOo"));
std::string newfoo(std::begin(up), std::end(up));
assert(newfoo == "FOO");

然后,类似于一个普通的迭代范围,你将需要创建一个范围类和一个迭代器类:

class myit
{
private:
    std::string::const_iterator wrapped_;
    class charholder
    {
        const char value_;
    public:
        charholder(const char value) : value_(value) {}
        char operator*() const { return value_; }
    };
public:
    // Previously provided by std::iterator
    typedef int                     value_type;
    typedef std::ptrdiff_t          difference_type;
    typedef int*                    pointer;
    typedef int&                    reference;
    typedef std::input_iterator_tag iterator_category;

    explicit myit(std::string::const_iterator wrapped) : wrapped_(wrapped) {}
    value_type operator*() const { return std::toupper(*wrapped_); }
    bool operator==(const myit& other) const { return wrapped_ == other.wrapped_; }
    bool operator!=(const myit& other) const { return !(*this == other); }
    charholder operator++(int)
    {
        charholder ret(std::toupper(*wrapped_));
        ++wrapped_;
        return ret;
    }
    myit& operator++()
    {
        ++wrapped_;
        return *this;
    }
};

class Upper
{
private:
    const std::string str_;
public:
    Upper(const std::string str) : str_(str) {}
    myit begin() { return myit(std::begin(str_)); }
    myit end()   { return myit(std::end(str_)); }
};

请注意需要调用转换/适应函数std::toupper在两个地方。更新:std::iterator在c++ 17中是不推荐的,因此被删除。

赞(0)
未经允许不得转载:srcmini » C++迭代器或包装器适配器示例

评论 抢沙发

评论前必须登录!