我有一个类/结构如下:
struct MyStruct {
std::string member_one;
std::string member_two;
};
我创建了一个MyStruct
,std::vector<MyStruct>
的向量,其长度为N
,成员设置为自定义值:
std::vector<MyStruct> my_struct_vect(10);
// initialize class instances
现在我想将第一个成员memberOne
提取到一个新的向量中。我可以这样做:
std::vector<std::string> member_one_vect(my_struct_vect.size());
for (size_t i = 0; i < my_struct_vect.size(); ++i) {
member_one_vect[i] = my_struct_vect[i].member_one;
}
我的问题是,是否有更快/更优雅/更清洁的方式,而无需每次都编写自定义循环?例如,在Python中,我可以通过理解很容易地做到这一点。我不希望在C ++中有类似的东西,但我想知道是否有某种方法可以简化这一点。
感谢您使用std::transform
和boost::adaptors::transformed
的精彩回复。这些非常有用,但为了紧凑,值得注意的是它们依赖于C ++ 11中引入的lambda函数(可以不使用它们,但这需要定义一个单独的辅助函数)。
所以对于奖励积分,有没有办法在C ++ 03中以紧凑的方式做到这一点?
答案 0 :(得分:5)
您可以使用std::transform
:
#include <algorithm> // Necessary for std::transform()
// ...
std::vector<std::string> member_one_vect(my_struct_vect.size());
std::transform(
my_struct_vect.begin(), my_struct_vect.end(), member_one_vect.begin(),
[] (MyStruct const& ms)
{
return ms.member_one;
});
以下是完整代码的外观:
#include <vector>
#include <string>
#include <algorithm>
struct MyStruct {
std::string member_one;
std::string member_two;
};
int main()
{
std::vector<MyStruct> my_struct_vect(10);
// Initialize my_struct_vect...
std::vector<std::string> member_one_vect(my_struct_vect.size());
std::transform(
my_struct_vect.begin(), my_struct_vect.end(), member_one_vect.begin(),
[] (MyStruct const& ms)
{
return ms.member_one;
});
// Do something with member_one_vect...
}
这是live example。
答案 1 :(得分:3)
您可以使用算法。
std::vector<std::string> member_one_vect(my_struct_vect.size());
std::transform(my_struct_vect.begin(), my_struct_vect.end(),
member_one_vect.begin(),
[](const MyStruct& m) { return m.member_one; });
此外,您可以使用boost::adaptors::transformed
。
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/copy.hpp>
std::vector<std::string> member_one_vect(my_struct_vect.size());
std::function<std::string(const MyStruct&)> transform =
[] (const MyStruct& m) { return m.member_one; };
boost::copy(my_struct_vect | boost::adaptors::transformed(transform),
member_one_vect.begin());