主要问题已在标题中:如何推进标准地图的迭代器?
但是由于大多数人都会问为什么我需要这个,我会提供更多信息: 我有一个有几张地图的课程。我有至少2个微分方程,至少2种传感器类型(场或dft)和至少2种空间类型(体积,表面)。我需要保存所有这些东西,并在它们之间建立关联。 所以我认为拥有这些东西的地图是明智的,当事物彼此相关时,它们的地图中都有相同的密钥。
为简单起见,我们只考虑三张地图。
class Reader
{
struct MaxwellSensor
{
// some members...
};
struct FieldSensor
{
// some members
uint fieldMember;
};
struct DFTSensor
{
// some members
uint dftMember;
};
std::map<uint, MaxwellSensor> maxwellSensors;
std::map<uint, FieldSensor> fieldSensors;
std::map<uint, DFTSensor> dftSensors;
uint getCountOfMaxwellSensors(){
return maxwellSensors.size();
}
uint getMemberForMaxwellSensorByIndex(uint index){
// This follows later
}
};
在我的程序过程中,我需要实例化SensorInterface
的几个变量。
为此我需要知道我有多少个麦克斯韦传感器,然后迭代通过麦克斯韦传感器并获得其他传感器的成员。
这看起来像:
class MyType{
public:
uint member;
}
int main(int argc, const char* argv[])
{
// some code
Reader myReader;
for(uint i = 0; i < myReader.countOfMaxwellSensors(); ++i)
{
MyType var;
var.member = myReader.getMemberForMaxwellSensorByIndex(i);
}
}
因此读者中的功能应如下所示:
uint getMemberForMaxwellSensorByIndex(uint index)
{
auto maxIt = std::advance(maxwellSensors.begin(), index);
auto foundInFieldSensorsIt = std::find_if(fieldSensors.begin(), fieldSensors.end(), [&] (const std::pair<UInteger_T, FieldSensor>& kvp) { return kvp.first == maxIt->first; });
auto foundInDFTSensorsIt = std::find_if(dftSensors.begin(), dftSensors.end(), [&] (const std::pair<UInteger_T, DFTSensor>& kvp) { return kvp.first == maxIt->first; });
if(foundInFieldSensorsIt != fieldSensors.end())
return fieldSensors[maxIt->first].fieldMember;
else if(foundInDFTSensorsIt != dftSensors.end())
return dftSensors[maxIt->first].fieldMember;
else
{
std::cerr << "something went wrong." << std::endl;
return 0;
}
}
所以......这是std::advance(maxwellSensors.begin(), index);
的意图但是这不能用这个错误代码编译:
error:
no matching function for call to 'advance'
auto maxIt = std::advance(maxwellSensors.begin(), index);
^~~~~~~~~~~~
/c++/4.6/bits/stl_iterator_base_funcs.h:171:5: note:
candidate function [with _InputIterator = std::_Rb_tree_iterator<std::pair<const
unsigned int, Reader<double, unsigned int>::MaxwellSensor> >,
_Distance = unsigned int] not viable: expects an l-value for 1st argument
advance(_InputIterator& __i, _Distance __n)
那么如何推进标准地图的迭代器呢?
我也试过auto maxIt = maxwellSensors.begin() + index;
,但没有运气。
并且:我想避免使用for循环:
auto maxIt = maxwellSensors.begin();
for(uint i = 0; i < index; ++i){
++maxIt;
}
还有其他可能吗? 非常感谢提前!
答案 0 :(得分:9)
iterator_category
的{{1}}是双向迭代器的std::map
。这意味着没有O(1)
多步增量,例如随机访问迭代器。对于后者,您可以写:
auto it = my_vector.begin(); // std::vector has random access iterators
std::advance(it, 4); // NOT a loop, will call it += 4;
it += 4; // shorthand, not recommended in generic code
对于前者,你有
auto it = my_map.begin(); // std::map has bidirectional iterators
std::advance(it, 4); // for (auto i = 0; i < 4; ++i) ++it;
请注意,std::advance
具有void
返回类型。如果要返回高级迭代器,可以使用std::next
auto it = my_map.begin();
auto it4 = std::next(it, 4); // copies it, then advances and returns that copy
std::advance
的步骤参数可以为负数,在这种情况下,它会调用--it
。如果要返回递减的迭代器,可以使用std::prev
。
答案 1 :(得分:3)
推进的原型是:
template <class InputIterator, class Distance>
void advance (InputIterator& it, Distance n);
所以你必须这样做:
auto maxIt = maxwellSensors.begin();
std::advance(maxIt, index);
而不是
auto maxIt = std::advance(maxwellSensors.begin(), index); // Failed
答案 2 :(得分:2)
你需要提供一个变量来推进。因此,以下内容将起作用:
auto it = maxwellSensors.begin();
std::advance(it, index);
然而,这内部只是做一个你想避免的循环。循环是推进地图迭代器的唯一方法。如果您使用向量或双端队列,则continer.begin() + index
有效,因为它们有Random Access iterators
,而地图则没有。
我认为你真正想要的是这个,它在你的地图中找到index
并返回一个迭代器:
auto it = maxwellSensors.find(index);
答案 3 :(得分:1)
请参阅预先签名和文档:http://en.cppreference.com/w/cpp/iterator/advance
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
这意味着正确的用法是:
auto maxIt = maxwellSensors.begin();
std::advance( maxIt , index);