基于循环和多个迭代器的范围

Mor*_*son 4 c++ iterator for-loop c++11 ranged-loops

我有以下代码,表示3D应用程序中的网格(为清晰起见,省略了一些代码):

class Mesh {
public:
    typedef std::vector<Vertex> Vertices;
    typedef std::vector<int> Elements;

    template<class VerticesIt, class ElementsIt>
    Mesh(const VerticesIt verticesBegin,
         const VerticesIt verticesEnd,
         const ElementsIt elementsBegin,
         const ElementsIt elementsEnd) :
    vertices_(verticesBegin, verticesEnd),
    elements_(elementsBegin, elementsEnd) {
    }        
    virtual ~Mesh();

    typename Vertices::const_iterator verticesBegin() const {
        return vertices_.begin();
    };

    typename Vertices::const_iterator verticesEnd() const {
        return vertices_.end();
    };

    typename Elements::const_iterator elementsBegin() const {
        return elements_.begin();
    };

    typename Elements::const_iterator elementsEnd() const {
        return elements_.end();
    };

private:       
    Vertices vertices_;
    Elements elements_;

};
Run Code Online (Sandbox Code Playgroud)

它工作得非常好,为内部数据提供了清晰的界面.没有为容器公开实现细节.

我对此有一点打嗝.我不能使用基于范围的循环,必须使用迭代器:

for (auto it = mesh.verticesBegin(); it != mesh.verticesEnd(); ++it) {
// Do stuff
}

for (auto it = mesh.elementsBegin(); it != mesh.elementsEnd(); ++it) {
// Do stuff
}
Run Code Online (Sandbox Code Playgroud)

我的口味有点冗长.我首选的客户端代码将如下所示:

for(auto & vert : mesh.vertices) {
// Do stuff.
}

for(auto & element : mesh.elements) {
// Do stuff.
}
Run Code Online (Sandbox Code Playgroud)

是否有可能在暴露容器实现细节的情况下实现这一目标?此外,我不想将容器包装到自定义类中,因为我想要在Mesh类中完全访问所选容器(std :: vector).

jho*_*n0x 9

您可以使用某种代理,例如:

template<typename Container>
class ConstIteratorProxy
{
public:
    ConstIteratorProxy(const Container& container) : container_(container) { }
    typename Container::const_iterator begin() const {
        return container_.begin();
    };
    typename Container::const_iterator end() const {
        return container_.end();
    };
private:
    const Container& container_;
};
Run Code Online (Sandbox Code Playgroud)

在网格中:

ConstIteratorProxy<Vertices> vertices() const {
    return ConstIteratorProxy<Vertices>(vertices_);
}
ConstIteratorProxy<Elements> elements() const {
    return ConstIteratorProxy<Elements>(elements_);
}
Run Code Online (Sandbox Code Playgroud)

然后使用它:

Mesh m;
for (auto& v : m.vertices()) { }
for (auto& e : m.elements()) { }
Run Code Online (Sandbox Code Playgroud)