給定一個對象矢量,是否有一種優雅的方法來提取其成員?我目前只是使用for循環,但如果有辦法做到這一點會很好。例如,從對象矢量中提取元素
class Object {
int x;
float y;
}
vector<Object> obj;
// Fill up obj
vector<int> all_x = obj.x // Won't work obviously
給定一個對象矢量,是否有一種優雅的方法來提取其成員?我目前只是使用for循環,但如果有辦法做到這一點會很好。例如,從對象矢量中提取元素
class Object {
int x;
float y;
}
vector<Object> obj;
// Fill up obj
vector<int> all_x = obj.x // Won't work obviously
由於std::vector
(或C++一般)不支持協變聚集,沒有語法上相當的方式做你想做的。
如果你真的想初始化all_x
與obj
元素x
成員,那麼你可以定義一個新的迭代器類,像:
class getx_iter : public vector<Object>::iterator
{
public:
getx_iter(const vector<Object>::iterator &iter) : vector<Object>::iterator(iter) {}
int operator*() { return (*this)->x; }
};
如果您能夠接受初始化一個空的vector
然後填充它,std::transform
與labmda是一個更清晰的選項(如@andars建議)。
您也可避免額外的初始化通過使用vector::reserve()
和back_inserter
:
xs.reserve(foos.size());
std::transform(foos.begin(), foos.end(), back_inserter(xs), [](Foo f){return f.x;});
還要注意的是,雖然x
是Object
私有成員並沒有干將,這將是十分困難的提取它。
我想不出一個很好的方法。
一種替代方案是使用std::transform
與拉姆達。
#include <vector>
#include <algorithm>
class Foo {
public:
Foo(int x_): x(x_) {}
int x;
};
int main() {
std::vector<Foo> foos;
for (int i = 0; i<10; i++) {
foos.push_back(Foo(i));
}
std::vector<int> xs;
xs.resize(foos.size());
std::transform(foos.begin(), foos.end(), xs.begin(), [](Foo f){return f.x;});
}
一些模板和宏觀魔法,它的工作原理:
#include <vector>
#include <algorithm>
using namespace std;
class Foo {
public:
Foo(int x_): x(x_) {}
int x;
};
#define GETFIELD(type, field) [](const type & obj){return obj.field;}
template<typename T,typename U, typename TMapper>
void MapVector(vector<T>& src, vector<U>& dst, TMapper mapper) {
for (const auto& it: src) {
dst.push_back(mapper(it));
}
}
#define MapVectorField(src, dst, field) MapVector(src, dst, GETFIELD(decltype(src)::value_type, field))
int main() {
vector<Foo> vFoo;
for (int i = 0; i < 10; i++) {
vFoo.push_back(Foo(i));
}
vector<int> vX;
MapVector(vFoo, vX, GETFIELD(Foo, x));
MapVectorField(vFoo, vX, x);
for (int i = 0; i < vX.size(); i++) {
printf("%d\n", vX[i]);
}
}
當然,記住,這不是很好的名字宏觀MapVectorField
,因爲它是功能,還是寫在生產using namespace std
。
您可以使用成員指針,而不是你的宏:'&富:: X '。 – Jarod42