您如何使用std :: distance查找指向std :: array元素的指针的数组索引?

时间:2018-07-24 00:40:12

标签: c++ c++11 iterator

假设我有一个对象的std :: array,并创建了一个指向其中一个对象的指针。

std::array<Object, 100> my_array;

Object* ptr_object = &my_array[50]; 

因此,假设我不知道ptr_object所引用的索引,我将如何在C ++ 11中继续查找该索引?

我发现一些建议std :: distance可能有助于我的尝试

std::distance(my_array, ptr_object);

引发错误,指出“未找到匹配的重载函数”。

2 个答案:

答案 0 :(得分:5)

获取索引的最简单方法是使用指针算法。只需从指向第一个元素的指针中减去指向所需元素的指针,例如:

size_t index = (ptr_object - my_array.data()/*&my_array[0]*/);

std::distance()将迭代器作为输入,并且原始指针可用作迭代器。因此,您可以将指向第一个元素的指针用作开始迭代器,并将指向所需元素的指针用作结束迭代器,例如:

size_t index = std::distance(my_array.data()/*&my_array[0]*/, ptr_object);

请注意,这与您尝试将std::array本身传递给std::distance()的代码有何不同。那是行不通的。

以上两者均具有恒定的复杂性,因为它们是简单的算术运算({std::distance()已针对随机访问迭代器进行了优化,例如原始指针和std::array迭代器)。

或者,您可以改用实际的迭代器,但这需要遍历数组以使迭代器到达所需元素,而无需事先知道其索引,例如:

auto iter = std::find_if(std::begin(my_array), std::end(my_array), [=](Object &o) { return (&o == ptr_object); });
size_t index = std::distance(my_array.begin(), iter);

答案 1 :(得分:2)

除非您的情况如此,否则我建议不要随意使用std::distance

std::distance是一种接口统一功能,其目的是允许人们计算各种迭代器之间的距离:随机访问,双向,正向等。此函数旨在掩盖直接计算的效率低下在您真的知道自己在做什么并且真的想接受这种低效率的情况下,非随机访问迭代器的距离。它旨在在您的代码中脱颖而出(像强制转换一样),表明通常情况下该代码可能效率低下,但您至少暂时不愿意接受,例如在临时“草图”代码中。 (std::advance也是如此)。

如果您不打算“隐藏”效率低下的问题,即您打算将代码仅与随机访问迭代器一起使用,请不要使用std::distance。只需减去迭代器

std::ptrdiff_t i = ptr_object - my_array.data();