【问题标题】:Passing pointer on vector's elements into map将向量元素的指针传递到地图中
【发布时间】:2020-12-18 12:50:02
【问题描述】:

以下函数必须在向量 allSportsmen 中按全名和出生日期找到运动员,然后按名称查找某项运动,并从向量中添加该运动员和该运动以映射参与者,其中键是运动员,值是运动他会的

 vector<Sportsman> allSportsmen;
 vector<Sport> allSports;
 map<Sportsman, vector<Sport>> participants;
 void addSportToSportsman(string fullName, string birthDate, string sportName) {
    Sportsman* s;
    Sport* sport;
    for (auto x = allSportsmen.begin(); x != allSportsmen.end(); x++) {
        if (x->getFullName() == fullName && x->getBirthDate() == birthDate)
        {
            for (auto y = allSports.begin(); y != allSports.end(); y++) {
                if (y->getSportName() == sportName)
                {
                    s = allSportsmen.at(x);
                    sport = allSports.at(y);
                    participants[s].push_back(sport);
                }
            }
        }
    }
}

在行:

s = allSportsmen.at(x);
sport = allSports.at(y);

我有错误:

C++ 没有重载函数实例匹配参数列表参数类型是: (std::_Vector_iterator<:_vector_val std::_simple_types std::_vec_iter_types size_t ptrdiff_t sportsman const>>>>) 对象类型为:std::vector

运动也是如此

然后:

编译器错误 C2679 二进制 '[' : 未找到采用 'std::_Vector_iteratorstd::_Vector_val<:_simple_types>>' 类型的右侧操作数的运算符(或没有可接受的转换)

如何解决此问题并正常传递存储在其向量中的运动员和运动?顺便说一句,这个地图是否应该接收像 map&lt;Sportsman*, vector&lt;Sport&gt;*&gt; participants;这样的指针

【问题讨论】:

    标签: c++ pointers stdvector stdmap


    【解决方案1】:

    如果您需要指针,则必须获取取消引用的迭代器的地址

    s = &(*x);
    sport = &(*y);
    

    然而,我会警告你,如果你改变你的向量 allSportsmenallSports(例如 push_backemplace_backresize 等)导致重新分配,这是一个脆弱的设计,你' 可能会使您的指针无效。

    另请注意,您必须更改地图的类型才能存储指针

    map<Sportsman*, vector<Sport*>> participants;
    

    【讨论】:

    • 建议的更改也很脆弱。随着向量的增长,指向其元素的指针将失效。因此地图的键和值将失效。并且键不按值比较,因此不可能按值找到键,您需要具有完全相同地址的对象。编辑:我不确定答案是否暗示了这一点,但这对我来说并不明显。
    【解决方案2】:

    以这些作为输入...

    vector<Sportsman> allSportsmen;
    vector<Sport> allSports;
    map<Sportsman, vector<Sport>> participants;
    

    ...我会稍微修改一下:

    • 删除 allSportsmen,因为地图中的 将提供相同的列表。
    • allSports 设为set&lt;Sport&gt;。它们应该是唯一的,而且,如果由于删除元素或添加新元素而移动了 vector 数据,则指向 vector 中元素的指针可能会失效。
    • maps vector 中存储迭代器,而不是指针。

    所以,这将是我的方法:

    std::set<Sport> allSports;
    std::map<Sportsman, std::vector<std::set<Sport>::iterator>> participants;
    

    Demo

    如果每个 Sportsman 都应该映射到一组独特的运动,您可以考虑将 vector 更改为 set,从而实现

    std::map<Sportsman, std::set<std::set<Sport>::iterator>> participants;
    

    如果顺序不重要,您可以改用 unordered 对应项。

    【讨论】:

    • 很多时候,vectors 中的map 可以改为multimap
    • @FrançoisAndrieux 你也许是对的。我必须承认我没有太多使用multimaps。 :) 在这种情况下,使用普通 map 的好处是它提供了一个唯一的 Sportsman 列表,这使得删除一个容器变得容易。
    • s = allSportsmen.at(x);:您正在将迭代器 x 发送到需要整数的函数。即使该操作是正确的,它也会返回一个 Sportsman 对象,您尝试将其分配给 Sportsman * 变量。以下sport = allSports.at(y); 有类似的错误。 Cory Kramer 的更正和批评似乎不错。
    • @TWBennet 你错过了我建议的大部分内容。我将迭代器x 发送到期望整数的函数(或者 - 我已经完成了 boo-boo)。再次阅读我的所有建议,您会发现返回值对于从 OP 获得的有限信息非常准确。我刚刚阅读了 OP 呈现的内容,但我无法以任何其他方式看到它的目的,然后是我最初所做的。 - 事实上 - 我对我的建议很有信心。
    • @TWBennet 只是为了明确一点,“您正在将迭代器 x 发送到需要整数的函数。”根本不是我的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 2022-01-12
    • 2019-04-09
    • 2011-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多