Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 基于范围的循环和多迭代器_C++_C++11_For Loop_Iterator_Ranged Loops - Fatal编程技术网

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

C++ 基于范围的循环和多迭代器,c++,c++11,for-loop,iterator,ranged-loops,C++,C++11,For Loop,Iterator,Ranged Loops,我有以下代码,表示3D应用程序中的网格(为了清晰起见,有些代码是经过修改的): 对我来说有点冗长。我首选的客户端代码将改为如下所示: for(auto & vert : mesh.vertices) { // Do stuff. } for(auto & element : mesh.elements) { // Do stuff. } 是否可以在不公开容器的实现细节的情况下实现这一点?另外,我不想将容器包装到自定义类中,因为我希望完全访问Mesh类中所选的容器(std::v

我有以下代码,表示3D应用程序中的网格(为了清晰起见,有些代码是经过修改的):

对我来说有点冗长。我首选的客户端代码将改为如下所示:

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

for(auto & element : mesh.elements) {
// Do stuff.
}

是否可以在不公开容器的实现细节的情况下实现这一点?另外,我不想将容器包装到自定义类中,因为我希望完全访问Mesh类中所选的容器(std::vector)。

分别将函数
verticesBegin
verticesEnd
重命名为
begin
end
。那么你就可以写下:

for(auto & vert : mesh) 
{
// Do stuff.
}
请注意,基于范围的
for
循环希望容器具有
开始
结束
作为成员函数,或者自由函数
开始
结束
,将容器作为参数

还要注意,基于范围的for循环不能迭代两件事-
mesh
可以像一个容器一样工作,而不是两个。所以,如果你想迭代索引,那么你必须公开它,或者抽象它,然后公开顶点


或者您可以编写一个zip迭代器,它将在一个for循环中同时在两个容器上进行迭代。

使用代理存储两个迭代器并实现begin和end方法非常简单:

#include <iostream>
#include <vector>

template <typename T>
struct PairIt {
    PairIt(T&& b, T&& e) : b_{std::forward<T>(b)}, e_{std::forward<T>(e)} {}
    T begin() const { return b_; }
    T end() const { return e_; }
private:
    T b_,e_;
};

std::vector<int> badglobal { 1, 2, 3 };

PairIt<std::vector<int>::iterator> ForRangeProxy() {
    return { begin(badglobal), end(badglobal) };
};

int main() {
    for( auto v : ForRangeProxy() )
        std::cout << v << std::endl;
}
#包括
#包括
模板
结构对{
PairIt(T&&b,T&&e):b{std::forward(b)},e{std::forward(e)}
T begin()常量{return b_;}
T end()常量{return e_;}
私人:
T b_,e_;
};
std::向量{1,2,3};
PairIt ForRangeProxy(){
返回{begin(BADGALOBAL),end(BADGALOBAL)};
};
int main(){
for(自动v:ForRangeProxy())

std::cout您可以从
顶点()
元素()
函数返回迭代器包装器,这些函数可以传递给for循环,例如

template<typename T>
class iterator_wrapper
{
public:
  iterator_wrapper(const typename std::vector<T>::const_iterator &begin_,
                   const typename std::vector<T>::const_iterator &end_)
    :m_begin(begin_), m_end(end_) {}
  typename std::vector<T>::const_iterator begin() const {return m_begin;}
  typename std::vector<T>::const_iterator end() const {return m_end;}

private:
  typename std::vector<T>::const_iterator m_begin, m_end;
};
那么就这样称呼它:

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

for(auto &element:mesh.elements())
{
  //....
}

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

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_;
};

+1但是,如果他也想迭代网格索引呢?这需要更多的努力,正如@Manu343726所说,我想以同样的方式迭代索引。我将在问题中澄清这一点。@MorganBengtsson:基于范围的for循环不能迭代两件事。
mesh
可以像一个容器,而不是两个.So如果你也想迭代索引,那么你必须公开它。或者写一个zip迭代器。我不知道为什么标准库中没有zip迭代器
iterator_wrapper<Vertex> vertices() {return iterator_wrapper<Vertex>(vertices_.begin(), vertices_.end());}
iterator_wrapper<int> elements()    {return iterator_wrapper<int>(elements_.begin(), elements_.end());}
for(auto &vert:mesh.vertices())
{
  //....
}

for(auto &element:mesh.elements())
{
  //....
}
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_;
};
ConstIteratorProxy<Vertices> vertices() const {
    return ConstIteratorProxy<Vertices>(vertices_);
}
ConstIteratorProxy<Elements> elements() const {
    return ConstIteratorProxy<Elements>(elements_);
}
Mesh m;
for (auto& v : m.vertices()) { }
for (auto& e : m.elements()) { }