问题描述
是否有一个迭代器,也许在标准库中,类似于 back_inserter
在被取消引用时调用函数的意义,当取消引用时,返回的不是它指向的项目,而是它的一个属性?
我想将迭代器带到自定义结构的容器(例如向量)的开头和结尾,并且我希望迭代器被取消引用以访问该结构的特定成员并直接对其进行处理。也许我可以通过让它在该元素上调用某种形式的 lambda 来定义该行为,然后返回所需的成员字段。
原因是我不想维护这些成员字段的单独容器。
像这样:
struct Person
{
std::string m_Name;
std::uint64_t m_Age;
};
int main()
{
std::vector<Person> people { Person("a",15),Person("b",25),Person("c",40) };
// MagicIterator is what I'm after
auto ageIter = MagicIterator(people,[](const Person &person) { return person.m_Age; });
// sample use case,foo here expects a container of arithmetic types
auto out = foo<std::uint64_t>(ageIter.begin(),ageIter.end());
return 0;
}
现在,我想我必须首先在一个单独的容器中提取所有年龄,然后将该新容器传递给我想避免的 foo
。
我对包括 C++17 在内的任何东西都很满意,Boost 也可以。
解决方法
您可以只使用 std::accumulate()
。
auto sumAges = std::accumulate(people.begin(),people.end(),[](const Person &person){ return person.m_Age; });
,
老实说,我想知道您是否没有不必要地使您的生活复杂化。
为什么不直接使用以下代码?
struct Person
{
std::string m_Name;
std::uint64_t m_Age;
};
int main()
{
std::vector<Person> people{ { "a",15 },{ "b",25 },{"c",40 } };
std::uint64_t sumAge = 0;
for(auto it=people.begin(); it!=people.end(); it++){
sumAge += it->m_Age;
}
return 0;
}
,
根据评论中的建议(并使用 this answer 作为基础),我想出了以下内容来满足我的需要(使用 std::accumulate
只是为了传递它可以直接对我的示例进行操作的东西):
#include <iostream>
#include <vector>
#include <numeric>
#include <boost/iterator/transform_iterator.hpp>
struct Person
{
std::string m_Name;
std::uint64_t m_Age;
Person(std::string name,std::uint64_t age) : m_Name{std::move(name)},m_Age{age} {}
};
int main()
{
std::vector<Person> people { Person("a",10),Person("b",15) };
// lambda that accesses the member field I need to use
auto ageGetter = [](const Person &person) { return person.m_Age; };
// begin and end iterators that underneath call my 'ageGetter'
auto begin = boost::make_transform_iterator(people.begin(),ageGetter);
auto end = boost::make_transform_iterator(people.end(),ageGetter);
// when run it prints 25,which is what I'd expect
std::cout << std::accumulate(begin,end,0) << std::endl;
return 0;
}