Как найти и вернуть элемент из std :: vector - PullRequest
3 голосов
/ 06 февраля 2020

В моей текущей ситуации у меня есть std::vector, заполненный Vector3f объектами (каждый со значениями x, y и z), действующими как мои sh вершины, я хочу получить свою позицию игрока (также Vector3f) ) и отправить его в функцию, которая может искать мах в объектах Vector3f в ранее упомянутом векторе вершин me sh и возвращать совпадающий Vector3f, чтобы я мог получить доступ к его компоненту y и использовать его для установки рост игроков.

Ближайшее, что я получил, - это ниже:

Vector3f Mesh::checkMeshVertices(Vector3f playerPos)
{
    return std::find(meshVertices.begin(), meshVertices.end(), playerPos) != meshVertices.end();
}

Однако, это просто вернет истину после матча, я хочу иметь возможность вернуть фактический Vector3f это был матч.

Ответы [ 2 ]

1 голос
/ 06 февраля 2020

Тип возвращаемого значения bool, в то время как тип возвращаемого значения функции Vector3f.

Поскольку возвращаемый тип не является ссылочным типом, то в случае, если вектор найден, вы можете использовать в вызывающей стороне передал аргумент. Таким образом, функция может просто возвращать значение типа bool, например

bool Mesh::checkMeshVertices(Vector3f playerPos)
{
    return std::find(meshVertices.begin(), meshVertices.end(), playerPos) != meshVertices.end();
}

, если вы хотите вернуть ссылку на найденный объект, то функция должна выдать исключение в случае, если объект не найден.

Например

Vector3d & Mesh::checkMeshVertices(Vector3f playerPos)
{
    auto it = std::find(meshVertices.begin(), meshVertices.end(), playerPos);
    if ( it != meshVertices.end() ) return *it;
    else throw std::out_of_range();
}
0 голосов
/ 06 февраля 2020

На самом деле, вы можете вернуть из вашей функции как логическое значение, которое указывает на успех в поиске элемента, так и фактический итератор для указанного элемента c (или найденного значения). Чтобы достичь этого, вы должны использовать функцию C ++ 17 под названием структурированное связывание .

. Вот простой код, который вы затем можете применить к вашему делу:

#include <vector>
#include <utility>
#include <iostream>
#include <algorithm>

std::pair<bool, std::vector<int>::const_iterator> find(std::vector<int> const& v, int number) {
    auto it = std::find(v.begin(), v.end(), number);
    if (v.end() == it) {
        return std::make_pair(false, it);
    }  else {
        return std::make_pair(true, it);
    }
}

int main() {
    std::vector<int> v = { 1, 2, 3, 4, 5 };
    if (auto [success, iter] = find(v, 5); success) {
        std::cout << "Found" << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }

    return 0;
}

Проверьте это вживую .

Применение этой логики c к вашему примеру будет выглядеть следующим образом:

std::pair<bool, std::vector<Vector3f>::const_iterator> Mesh::checkMeshVertices(Vector3f playerPos) {
    auto it = std::find(meshVertices.begin(), meshVertices.end(), playerPos);
    if (meshVertices.end() == it) {
        return std::make_pair(false, it);
    } else {
        return std::make_pair(true, it);
    }
}

ОБНОВЛЕНИЕ

Вы также можете использовать std::optional вот так:

#include <vector>
#include <iostream>
#include <optional>
#include <algorithm>

std::optional<std::vector<int>::const_iterator> find(std::vector<int> const& v, int number) {
    auto it = std::find(v.begin(), v.end(), number);
    if (v.end() == it) {
        return {}; // or return std::nullopt;
    }  else {
        return it;
    }
}

int main() {
    std::vector<int> v = { 1, 2, 3, 4, 5 };

    auto iter = find(v, 6);
    if (iter) {
        std::cout << "Found" << std::endl;
    } else {
        std::cout << "Not found" << std::endl;
    }

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...