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

Izz*_*zzo 0 c++ iterator c++11

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

std::array<Object, 100> my_array;

Object* ptr_object = &my_array[50]; 
Run Code Online (Sandbox Code Playgroud)

所以假设我不知道ptr_object引用的索引,我将如何在C++ 11中查找和索引这个索引?

我发现一些读数表明std :: distance可能会有所帮助,但是,我的尝试

std::distance(my_array, ptr_object);
Run Code Online (Sandbox Code Playgroud)

抛出错误,指出"找不到匹配的重载函数".

Rem*_*eau 5

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

size_t index = (ptr_object - my_array.data()/*&my_array[0]*/);
Run Code Online (Sandbox Code Playgroud)

std::distance()将迭代器作为输入,原始指针可以用作迭代器.因此,您可以使用指向第一个元素的指针作为起始迭代器,并使用指向期望元素的指针作为结束迭代器,例如:

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

请注意这与您尝试将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);
Run Code Online (Sandbox Code Playgroud)


AnT*_*AnT 5

我建议不要无端使用std::distance,除非这是您的要求。

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

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

std::ptrdiff_t i = ptr_object - my_array.data();
Run Code Online (Sandbox Code Playgroud)