迭代自定义对象 vector 但仅访问单个成员以应用通用 STL 算法的快速方法是什么?
struct Foo
{
std::string a;
double b = 1.0;
};
int main()
{
std::vector<Foo> fooVector(20);
// iterate over all members b -- as if we were iterating over a std::vector<double>
std::discrete_distribution<int> dist(/*??*/, /*??*/);
}
我的意思是“快”
- 没有自定义迭代器——或者只有一个非常轻量级的迭代器(——几行代码,没有 boost
iterator_facade
等), - 不修改取消引用运算符(--没那么快)。
最佳答案
std::discrete_distribution<...>
的构造函数不支持任何显式投影值的方式(如函数对象可选地应用于在使用前转换 *it
的结果)。因此,我认为存在三种基本方法:
使用中间体
std::vector<double>
获取其迭代器产生 double 值的范围:std::vector<double> tmp; // reserve() as desired std::transform(fooVector.begin(), fooVector.end(), std::back_inserter(tmp), [](Foo const& f){ return f.b; }); std::discrete_distribution<int> d(tmp.begin(), tmp.end());
在
Foo
上使用转换运算符可能是可行的转换成double
:class Foo { // ... operator double() const { return this->b; } }; // ... std::discrete_distribution<int> d(fooVector.begin(), fooVector.end());
为迭代器创建一个包装器并使用它。它不需要任何花哨的东西,但将一个简单的输入迭代器放在一起仍然比较复杂:
template <typename InIt> class project_iterator { InIt it; public: explicit project_iterator(InIt it): it(it) {} double operator*() const { return *this->it; } project_iterator& operator++() { ++this->it; return *this; } project_iterator operator++(int) { project_iterator rc(*this); this->operator++(); return *this; } bool operator==(project_iterator const& other) const { return this->it == other.it; } bool operator!=(project_iterator const& other) const { return !(*this == other); } }; template <typename It> project_iterator<It> project(It it) { return project_iterator<It>(it); } namespace std { template <typename It> class iterator_traits<project_iterator<It> { public: typedef typename std::iterator_traits<It>::difference_type difference_type; typedef double value_type; typedef double& reference; typedef double* pointer; typedef std::input_iterator_tag iterator_category; } } // ... std::discrete_distribution<int> d(project(fooVector.begin()), project(fooVector.end());
显然,这些方法有多种变体,但我认为没有其他方法可以巧妙地完成。本质上缺少的是对序列进行投影的一般方法(我通常将它们称为 property maps )。
关于C++ 迭代对象 vector 并将 STL 算法应用于成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34198818/