Как правильно использовать std :: transform и std :: mem_fn? - PullRequest
1 голос
/ 06 января 2020

Я реализовал программу на C ++, которая создает три разных объекта Person. Эти объекты делятся и хранятся в векторе.

Функция getVector() принимает const std::vector<std::shared_ptr<Person>>& в качестве ввода и возвращает std::vector<Person*>. Каждый элемент в векторе результатов соответствует соответствующему элементу во входном векторе.

Функция использует std::transform вместе с std::mem_fn.

Реализация этой функции (и соответствующий вызов с std::cout) не работает. Я думаю, что я неправильно использую std::transform с std::mem_fn (неверные аргументы и т. Д. c.).

Я не знаю, как заставить функцию getVector() работать.

Вот мой исходный код:

main. cpp

#include <string>
#include <vector>
#include <memory>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>

struct Person
{
    std::string first_name;
    std::string last_name;
    int age;

    Person* getPerson(const std::shared_ptr<Person>& person)
    {
        Person* p = person.get();
        return std::move(p);
    }

    // Overloaded << operator.
    friend std::ostream& operator<<(std::ostream& os, const Person& person)
    {
        os << person.first_name << ", " << person.last_name << ", " << person.age << "\n";
        return os;
    }

    friend std::string to_string(const Person& obj)
    {
        std::ostringstream ss;
        ss << obj;
        return ss.str();
    }
};

std::vector<Person*> getVector(const std::vector<std::shared_ptr<Person>>& people);

int main(void)
{
    Person person01;
    person01.first_name = "Ashley";
    person01.last_name = "Graham";
    person01.age = 23;

    Person person02;
    person02.first_name = "Ada";
    person02.last_name = "Wong";
    person02.age = 45;

    Person person03;
    person03.first_name = "Leon S.";
    person03.last_name = "Kennedy";
    person03.age = 26;

    std::shared_ptr<Person> ps01 = std::make_shared<Person>(person01);
    std::shared_ptr<Person> ps02 = std::make_shared<Person>(person02);
    std::shared_ptr<Person> ps03 = std::make_shared<Person>(person03);

    std::vector<std::shared_ptr<Person>> peoples;

    peoples.emplace_back(std::move(ps01));
    peoples.emplace_back(std::move(ps02));
    peoples.emplace_back(std::move(ps03));

    std::cout << "\nContent of input vector:\n";
    std::cout << "====================================\n";
    for (auto p : peoples)
    {
        std::cout << *p;
    }
    std::cout << "\n";

    std::cout << "Calling function 'getVector()'...\n";

    std::vector<Person*> result = getVector(peoples);

    std::cout << "\nContent of result-vector:\n";
    std::cout << "====================================\n";
    for (auto r : result)
    {
        std::cout << *r;
    }
    std::cout << "\n";

    return 0;
}

// std::transform with std::mem_fn.
std::vector<Person*> getVector(const std::vector<std::shared_ptr<Person>>& people)
{
    Person* person;
    std::shared_ptr<Person> p;
    std::vector<Person*> result;

    std::transform(people.begin(), people.end(), std::back_inserter(result), 
        std::bind1st(std::mem_fn(&Person::getPerson), &p));

    return result;
}

Вот инструкции для компилятора g ++:

g++ -std=c++11 -Wall -Wextra main.cpp -o main

1 Ответ

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

Просто используйте лямбду. Это делает код намного проще для понимания, и вы можете избавиться от функции GetPerson. Это сделает ваш вызов преобразования похожим на

std::transform(people.begin(), 
               people.end(), 
               std::back_inserter(result), 
               [](const auto& elem){ return elem.get(); });
...