首页 > 解决方案 > 如何从对其中一个项目的引用中获取 std::vector 元素的索引?

问题描述

您将如何优雅地(并以现代 C++ 方式)编写一个函数,该函数返回向量元素的索引,将此向量作为参数,并引用其中一个元素?

异常处理将不胜感激。

#include <vector>

template <class T>
std::size_t GetIndexFromRef(std::vector<T> &vec, T &item)
{
...
};

标签: c++

解决方案


这可以解决问题:

template <class T>
std::size_t GetIndexFromRef(std::vector<T> const &vec, T const &item)
{
    T const *data = vec.data();

    if(std::less<T const *>{}(&item, data) || std::greater_equal<T const *>{}(&item, data + vec.size()))
        throw std::out_of_range{"The given object is not part of the vector."};
    
    return static_cast<std::size_t>(&item - vec.data());
};

我正在使用std::lessand std::greater_equal,因为([comparisons.general§2]):

对于模板lessgreaterless_­equalgreater_­equal,任何指针类型的特化都会产生与实现定义的严格指针总顺序一致的结果 ([defns.order.ptr])。
[注 1:If对于指针和类型a < b是明确定义的,那么,,等等。——尾注]abP(a < b) == less<P>()(a, b)(a > b) == greater<P>()(a, b)

否则,与不属于向量的对象进行比较将是 UB。


推荐阅读