Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.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
C++ 如何从c++;?_C++_Arrays_Class_Mapping - Fatal编程技术网

C++ 如何从c++;?

C++ 如何从c++;?,c++,arrays,class,mapping,C++,Arrays,Class,Mapping,假设我有一个“person”对象数组: #包括 班主任{ 公众: 智力年龄; std::字符串名; }; 是否有可能获得一个与每个人的年龄(或姓名)相同大小的数组?我知道如何使用循环来实现这一点,但我希望有某种“映射”可以在一行中实现同样的效果。是的,您可以对传统阵列和标准容器(如std::vector)使用transform) 使用传统阵列 person persons[2] = { { 20, "name1" }, { 21, "name2" } }; for (auto & pe

假设我有一个“person”对象数组:

#包括
班主任{
公众:
智力年龄;
std::字符串名;
};

是否有可能获得一个与每个人的年龄(或姓名)相同大小的数组?我知道如何使用循环来实现这一点,但我希望有某种“映射”可以在一行中实现同样的效果。

是的,您可以对传统阵列和标准容器(如
std::vector
)使用
transform

使用传统阵列

person persons[2] = { { 20, "name1" }, { 21, "name2" } };
for (auto & person : persons)
    cout << person.age << " " << person.name << endl;

decltype(person::age) ages[sizeof(persons)/sizeof(persons[0])];
std::transform(std::begin(persons), std::end(persons), std::begin(ages), [](person & p) -> decltype(person::age) { return p.age; });
for (auto & age : ages)
    cout << age << endl;

这将动态提取原始容器中所有人员的年龄。

出于一般性考虑,我假设array是指动态大小的数组,那么完整示例将是:

#include <string>
struct person {
   int age;
   std::string name;
};

std::vector<int> getAge(std::vector<person> p) { 
   std::vector<int> result;
   result.reserve(p.size());
   for (auto& e : p) result.push_back(e.age);
   return result;
}

在任何情况下,都没有从实例数组中获取成员数组的神奇方法。必须在某个地方有一个循环(transform在向您隐藏该循环方面做得非常好)。

以下是使用lambda的方法:

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

struct person{
   int age;
   std::string name;
};

int main()
{
    std::vector<person> pp = {{16, "Bob"},{32, "Alice"}};
    std::vector<int> ages;
    std::transform(
        pp.begin(), 
        pp.end(), 
        std::back_inserter(ages),
        [](const person& p) -> int { return p.age; });
    for(auto v: ages)
        std::cout << v << " ";
}


更新:为了避免不必要的重新分配,可以在调用
std::transform

之前调用
ages.reserve(pp.size())
。但是,不确定这是否不是太令人难以承受的。无论您是否是编写它的人,都会有一个循环。使用:
persons | ranges::view::transform(&Person::age)
@AndyG这是编写循环的一个可怕原因。尽管像
std::copy
std::transform
这样的大多数算法都只是简单的循环,但它们极大地提高了可读性。每次你不用手动编写循环就能成功。@nwp:我同意。OP说他们想避免循环,但我想说这最终是不可避免的。@Ron是的,修正了。直到现在我才发现OP要求的是一艘班轮。然而,无论是编写函数还是使用算法,都可以在一行中完成,并且直接可见或不可见,必须有一个循环
#include <string>
struct person {
   int age;
   std::string name;
};

std::vector<int> getAge(std::vector<person> p) { 
   std::vector<int> result;
   result.reserve(p.size());
   for (auto& e : p) result.push_back(e.age);
   return result;
}
#include <algorithm>
int  main() {
    std::vector<person> foo(10);
    std::vector<int>    ages(10);
    std::transform(foo.begin(),foo.end(),ages.begin(),[](person& p){return p.age;});
}
#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

struct person{
   int age;
   std::string name;
};

int main()
{
    std::vector<person> pp = {{16, "Bob"},{32, "Alice"}};
    std::vector<int> ages;
    std::transform(
        pp.begin(), 
        pp.end(), 
        std::back_inserter(ages),
        [](const person& p) -> int { return p.age; });
    for(auto v: ages)
        std::cout << v << " ";
}
16 32