Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何正确使用std::transform和std::mem_fn? 我已经实现了一个C++程序,它创建了三个不同的人对象。这些对象被共享并存储在向量中_C++_Stl_Shared Ptr_Stdvector - Fatal编程技术网

如何正确使用std::transform和std::mem_fn? 我已经实现了一个C++程序,它创建了三个不同的人对象。这些对象被共享并存储在向量中

如何正确使用std::transform和std::mem_fn? 我已经实现了一个C++程序,它创建了三个不同的人对象。这些对象被共享并存储在向量中,c++,stl,shared-ptr,stdvector,C++,Stl,Shared Ptr,Stdvector,函数getVector()将const std::vector&作为输入,并返回std::vector。结果向量中的每个元素对应于输入向量中的各个元素 该函数与std::mem\fn一起使用std::transform 该函数的实现(以及使用std::cout的相应调用)不起作用。我认为我使用std::transform和std::mem_fn的方式是错误的(错误的参数等) 我不知道如何使函数getVector()工作 以下是我到目前为止的源代码: main.cpp #include <s

函数
getVector()
const std::vector&
作为输入,并返回
std::vector
。结果向量中的每个元素对应于输入向量中的各个元素

该函数与
std::mem\fn
一起使用
std::transform

该函数的实现(以及使用
std::cout
的相应调用)不起作用。我认为我使用
std::transform
std::mem_fn
的方式是错误的(错误的参数等)

我不知道如何使函数
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;
}

就用一个兰姆达。它使代码更容易理解,并且可以去掉
GetPerson
函数。这样做会使您的转换调用看起来像

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

auto elem
const auto&elem
之间是否存在显著差异?@Quest在这种情况下,是的。仅仅使用
auto
就可以制作一个副本,这是不必要的,因为
shared\u ptr
在原子级上非常昂贵。通过参考,我们降低了所有成本。如果它类似于
int
,只要不需要更新它的值,我就按值取。“auto elem和const auto&elem之间有显著差异吗?”-是的。一个复制了一个(可能很昂贵的复制对象),另一个没有。@NathanOliver非常感谢您的回复。源代码只是一个很小的示例,因此删除了不相关的部分。我已经用两种方法实现了
getVector()
函数:lambda表达式(工作)和
std::transform
std::mem_fn
(不工作)。我想知道如何使用
std::transform
std::mem\fn
实现该函数,以便比较这两个函数(可读性和编程工作量)。@rainer。使用
mem\u fn
真的没有一个好方法可以做到这一点。由于
GetPerson
是一个非静态成员函数,您需要有一个
Person
实例,它用来调用函数。您必须将
Person
绑定到
mem\u fn
的返回,并为转换要传递给它的共享指针添加一个
占位符。那看起来像
人p;std::transform(…,std::bind(std::mem_fn(&Person::getPerson),p,_1))但此时您可以直接使用bind。FWIW,就用一个lambda。这是标准的对流,大多数人都理解它们。
std::move
指针(如
std::move(p)
中的
getPerson
)是毫无意义的。只需返回指针。@PeteBecker它比无意义更糟糕,它可能会对编译器完成的RVO感到悲观。。如果您想让
bind1st
工作,请将
getPerson
的签名更改为不带参考的
shared\u ptr
。现在的问题是
operator()(const shared_ptr&)
binder1st
中有两个相同的重载。
std::transform(people.begin(), 
               people.end(), 
               std::back_inserter(result), 
               [](const auto& elem){ return elem.get(); });