Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.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::vector中的每个结构中选择一个成员到另一个向量中 我有一个VisualStudio 2008 C++项目,我想将一个结构类型的向量的一个结构元素复制到一个新的向量中。例如: struct Foo { int a; long b; }; std::vector< Foo > v1; std::vector< long > v2; for( std::vector< Foo >::const_iterator it = v1.begin(); it != v1.end(); ++it ) { v2.push_back( it->b ); } structfoo{ INTA; 长b; }; std::vectorv1; std::vectorv2; 对于(std::vector::const_迭代器it=v1.begin();it!=v1.end();++it) { v2.推回(it->b); }_C++_Stl - Fatal编程技术网

从std::vector中的每个结构中选择一个成员到另一个向量中 我有一个VisualStudio 2008 C++项目,我想将一个结构类型的向量的一个结构元素复制到一个新的向量中。例如: struct Foo { int a; long b; }; std::vector< Foo > v1; std::vector< long > v2; for( std::vector< Foo >::const_iterator it = v1.begin(); it != v1.end(); ++it ) { v2.push_back( it->b ); } structfoo{ INTA; 长b; }; std::vectorv1; std::vectorv2; 对于(std::vector::const_迭代器it=v1.begin();it!=v1.end();++it) { v2.推回(it->b); }

从std::vector中的每个结构中选择一个成员到另一个向量中 我有一个VisualStudio 2008 C++项目,我想将一个结构类型的向量的一个结构元素复制到一个新的向量中。例如: struct Foo { int a; long b; }; std::vector< Foo > v1; std::vector< long > v2; for( std::vector< Foo >::const_iterator it = v1.begin(); it != v1.end(); ++it ) { v2.push_back( it->b ); } structfoo{ INTA; 长b; }; std::vectorv1; std::vectorv2; 对于(std::vector::const_迭代器it=v1.begin();it!=v1.end();++it) { v2.推回(it->b); },c++,stl,C++,Stl,有比这更好/更优雅的方式吗 谢谢, PaulH < P>在Visual C++ 2008中,不,这是“优雅”的。标准库提供了可用于操作容器的算法,但在大多数情况下——特别是在像这样的简单用例中——它们太麻烦而无法使用 C++ 11将lambda表达式添加到C++中。Visual C++ 2010和其他C++编译器的最新版本支持C++ 11的特性。使用lambda表达式,您可以轻松地使用变换算法执行任务: std::transform(v1.begin(), v1.end(), std::ba

有比这更好/更优雅的方式吗

谢谢,
PaulH

< P>在Visual C++ 2008中,不,这是“优雅”的。标准库提供了可用于操作容器的算法,但在大多数情况下——特别是在像这样的简单用例中——它们太麻烦而无法使用

C++ 11将lambda表达式添加到C++中。Visual C++ 2010和其他C++编译器的最新版本支持C++ 11的特性。使用lambda表达式,您可以轻松地使用

变换
算法执行任务:

std::transform(v1.begin(), v1.end(), std::back_inserter(v2),
               [](Foo const& x) { return x.b; });
如果没有lambda表达式,则必须定义一个函数来从结构中提取
b
元素:

long get_b(Foo const& x) { return x.b; }
然后,您可以将此函数与
变换
算法一起使用:

std::transform(v1.begin(), v1.end(), std::back_inserter(v2), get_b);

然而,对于像这样的简单用例,这可能会很快导致难以处理的代码,因为很难将所有相关函数整齐地放在一起。

这实际上取决于“更好”的含义

如果您的意思是,如果可以使用模板欺骗来编写相同的内容,那么答案是肯定的:

template<typename C, typename T>
struct MemberGetter
{
    T C::*mp;
    MemberGetter(T C::*mp) : mp(mp) { }
    T operator()(const C& c) { return c.*mp; }
};

struct Foo
{
    double dm;
};

...
std::vector<double> x;
std::vector<Foo> y;

std::transform(y.begin(), y.end(),
               std::back_inserter(x),
               MemberGetter<Foo, double>(&Foo::dm));
模板
结构成员获取程序
{
TC::*mp;
MemberGetter(tc::*mp):mp(mp){}
T运算符()(常量C&C){返回C.*mp;}
};
结构Foo
{
双dm;
};
...
std::向量x;
std::向量y;
std::transform(y.begin(),y.end(),
标准:背面插入器(x),
MemberGetter(&Foo::dm));
在我看来,这比显式循环更糟糕,但其优点是成员指针(即复制结构的哪一部分)可以是运行时参数


如果您需要复制的成员是已知的和固定的,那么我会说显式循环是最好的方法(我几乎无法想象在某些情况下使用类似的模板,其中成员指针是模板参数会有任何意义)。

当然,还有其他技术,比如Boost.Lambda,或者编写通用的转换器,并将其与标准库绑定器一起使用,但这些技术都比不上原始代码中的技术。您还可以使用
std::bind(&Foo::b)
获得签名函数
long&(Foo&)
,我想。我已经试着完全把
bind
从我的记忆中抹去,尽管我担心有些伤疤会永远留在我的记忆中-O@Kerrek:当然包括缺少的占位符。@6502:将lambda与
转换
一起使用的唯一原因是,它使代码比使用
MemberGetter
std::bind
或相关技术更简单、更容易理解。在大多数情况下,算法优于循环,这是出于同样的原因:它们使代码更清晰、更简单、更容易理解。请参阅我对的回答,了解我为什么主张在循环上使用算法。