2012-04-27 7 views
2

有一个向量的迭代器。我想知道迭代器指向哪个索引。所以我做了以下,但我不确定。迭代器指向哪个索引

int temp = -1; 
std::vector <int> ::iterator f; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    if (*f == face) 
{ 
    switch (f-eFace[e].begin()) 
    { 
     case 0: 
     temp = 5;         
     break; 
     case 1: 
     temp = 3; 
     break; 
     case 2: 
     temp = 4; 
     break; 
     case 3: 
     temp = 1; 
     break; 
     case 4: 
     temp = 2; 
     break; 
     case 5: 
     temp = 0; 
     break; 
      default: 
     throw; 
    } 

    break; 
    } 
} 
+1

你更大的目标是什么?你确定你同时需要迭代器和索引吗? – 2012-04-27 10:53:22

+0

@ phresnel,我觉得这对输出最有用。我会冒险猜测目标可能是一样的。 – chris 2012-04-27 10:55:22

回答

2

为什么不能是这样的:

std::vector <int> ::iterator f; 

int index = 0; 

for (f=eFace[e].begin(); f!=eFace[e].end(); ++f) 
{ 
    // do sth 

    index++; 
} 
+1

@larsmans:增量是一个恒定的时间操作。 – 2012-04-27 10:51:21

+1

而在较大的循环中,与每次减去/调用距离相比,这会在时间上产生相当大的差异。 – chris 2012-04-27 10:52:28

+2

为什么不把'index'的增量与'f'的增量并置以避免它们不同步? – 2012-04-27 11:13:49

4
std::vector<int>::size_type index = std::distance (eFace [e].begin(), f); 

请注意,如果你虽然执行它的每一个循环会很慢。为载体另一种选择是:

std::vector<int>::size_type index = f - eFace [e].begin(); 

这工作,因为矢量使用随机访问迭代器,这是需要有减法定义,如下面史蒂夫·杰索普指出。

+0

我不确定标准是否真的需要它,但是如果'std :: distance'对于标记为随机访问的迭代器(哪些向量迭代器)没有恒定的时间复杂度,那么这是很糟糕的QoI,即使它符合。请注意,随机访问迭代器的减法定义为'b - a ==(a 2012-04-27 11:41:59

+0

@SteveJessop,这是一个有趣的观点。我不知道减法是这样执行的。我的回答指出,比建立索引变量和递增索引变量的两个不同部分更单线。在更大的循环中它效率相当低。 – chris 2012-04-27 11:44:36

+0

在实践中,我期望减法*不是这样实现的,它只是在标准中将结果定义为该值。因此,如果我们猜测“距离”的实施速度非常慢,我们可以推测减法也是愚蠢的。事实上,它们在任何适合实际使用的实现中都会很快。顺便说一句,减法工作的向量不是存储是连续的,而是迭代器是随机访问,因此必须有减法定义。例如,'deque'使用非连续存储,但迭代器减法也适用于此。 – 2012-04-27 11:46:39

0

对于你的问题:“我想知道哪些指标呢迭代器,指向。”通过说std::vector<int>::iterator f = eFace.begin();您正在创建一个类似于索引std::vector<int>::size_type i = 0;的interator。

你们用eFace.begin()!= eFace.end()通过向量与for循环行走时要使用i = 0!= eFace.size()以同样的方式迭代器。

至少我认为这就是你的原始问题。

2

获得更清晰的代码会容易得多。

首先,在向量找到一个值:

// Returns the index of `face` in `vec`. 
// If `face` is not present in `vec`, returns `vec.size()`. 
size_t findFaceIndex(int const face, std::vector<int> const& vec) { 
    std::vector<int>::const_iterator const it = 
     std::find(vec.begin(), vec.end(), face); 

    return it - vec.begin(); 
} 

现在映射:

static int const FaceMap[] = { 5, 3, 4, 1, 2, 0 }; 
static size_t const FaceMapSize = sizeof(FaceMap)/sizeof(int); 

// Translate face index into ... 
int faceIndexToX(size_t const index) { 
    if (index >= FaceMapSize) { throw std::runtime_error("out of bounds"); } 
    return FaceMap[index]; 
} 
+0

其中的第一个当然可以模板化。一般来说,如果任何人使用std :: find,因为它使用线性搜索,所以会出现警告标志。在极少数情况下,这种情况已经足够好了,小的收集很少被调用。 你的第二个解决方案是更好,尽管没有像std :: runtime_exception这样的异常(有runtime_error但std :: out_of_range可能是更好的像vector :: at那样抛出,尽管我更喜欢context或an assert。 – CashCow 2012-04-27 11:48:15

+0

@CashCow:我考虑过一个'std :: array',但我不确定OP是否是C++ 11精明的。当然这会更容易。 – 2012-04-27 12:26:44

0

我不知道为什么你时,你有迭代反正需要一个数组的索引?如果迭代器是随机访问你可以begin()减去它,但如果索引是如此重要,我不知道你最好只使用它而不是迭代器 - 当然这取决于你是否有权访问代码重构它。

我不确定你试图用你的开关实现什么,但如果它是映射值,那么推测稀疏向量会更合适?