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

C++ 如何使用std::distance查找指向std::数组元素的指针的数组索引?,c++,c++11,iterator,C++,C++11,Iterator,假设我有一个对象的std::数组,并创建一个指向其中一个对象的指针 std::array<Object, 100> my_array; Object* ptr_object = &my_array[50]; 抛出一个错误,指出“找不到匹配的重载函数”。获取索引的最简单方法是使用指针算法。只需从指向第一个元素的指针中减去指向所需元素的指针,例如: size_t index = (ptr_object - my_array.data()/*&my_array[0]*

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

std::array<Object, 100> my_array;

Object* ptr_object = &my_array[50]; 

抛出一个错误,指出“找不到匹配的重载函数”。

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

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);

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

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);

我建议不要无缘无故地使用
std::distance
,除非这是您的要求

std::distance
是一个接口统一函数,其目的是允许计算各种迭代器之间的距离:随机访问、双向、前向等。此函数旨在隐藏直接计算非随机访问迭代器距离的低效性,在这种情况下,你真的知道自己在做什么,真的想接受这种低效。它的目的是在代码中脱颖而出(如cast),表明在一般情况下代码可能效率低下,但至少在目前,您愿意接受这一事实,如在临时“草图”代码中。(这同样适用于
std::advance

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

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

我建议不要无缘无故地使用
std::distance
,除非这是您的要求

std::distance
是一个接口统一函数,其目的是允许计算各种迭代器之间的距离:随机访问、双向、前向等。此函数旨在隐藏直接计算非随机访问迭代器距离的低效性,在这种情况下,你真的知道自己在做什么,真的想接受这种低效。它的目的是在代码中脱颖而出(如cast),表明在一般情况下代码可能效率低下,但至少在目前,您愿意接受这一事实,如在临时“草图”代码中。(这同样适用于
std::advance

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

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


发布一些可编译的代码,说明您正在尝试执行的操作。@NeilButterworth我相信我发布的是一个简洁明了的问题。您需要从数组开始到
ptr_object
的距离,因此必须编写一些指定数组开始的内容(而不是像您所做的那样指定整个数组)@NeilButterworth这与问题无关如果要使用
std::distance()
,则需要将
std::begin(my_array)
作为其第一个参数,不是
my_array
本身。发布一些可编译的代码,说明您正在尝试执行的操作。@NeilButterworth我相信我发布的是一个简洁明了的问题。您需要从数组开始到
ptr_对象的距离,因此您必须编写一些指定数组开始的内容(不是你所做的整个数组)@NeilButterworth这与问题无关如果你想使用
std::distance()
,那么你需要将
std::begin(my_array)
作为它的第一个参数,而不是
my_array
本身。你有什么理由更喜欢
my_array.data()
而不是
my_array.begin()
?另一个选项是
&my_array[0]
@M.M yes,前提是
N>0
。尽管
begin()
data()
和[0]
稍微干净一些,而且更像STL。@PaulRooney:
data()
是指向第一个元素的指针。
begin()
是第1个元素的迭代器。指针始终可以用作迭代器,但迭代器并不总是指针。是的,我理解这一区别。我只是好奇在任何情况下使用
begin
是否都是错误的。是否有理由更喜欢
my_array.data()
而不是
my_arra