跳过 unordered_map 的第一次迭代
Skip first iteration over unordered_map
在使用 auto
的 for
循环中,迭代器迭代 unordered_map
。像这样:
using RuleIndex = std::unordered_map<uint, Symbol*>;
RuleIndex rule_index;
for(const auto & rule_pair : rule_index ) {
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
假设所有变量都已正确定义,因为代码运行良好。我的问题是,如何排除第一次迭代?例如,地图包含 3 行,当前循环迭代 0、1、2。我只想迭代 1 和 2。
bool is_first_iteration = true;
for(const auto & rule_pair : rule_index) {
if (std::exchange(is_first_iteration, false)) continue;
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
std::exchange
调用将 false
分配给 is_first_iteration
和 returns 先前的值。这实际上是 the paper proposing std::exchange
for C++14 中讨论的用例之一。该论文还展示了一个参考实现,如果您坚持使用 C++11,则可以使用它。
如果您不能使用 std::exchange(由于 C++11 的限制),这个简单的解决方案也可以工作:
bool is_first_iteration = true;
for (const auto & rule_pair : rule_index)
{
if (is_first_iteration)
{
is_first_iteration = false;
continue;
}
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
我有时使用的一个简洁的 C++11 选项,它也保留了一个有时很方便的计数器。我在下面展示了 if (i++)
,它依赖于 0
转换为 false
,而其他数字转换为 true
,但如果你是,你可以输入 if (++i > 1)
更舒服:
size_t i = 0;
for (const auto & rule_pair : rule_index)
if (i++)
{
...
}
...或if (++i == 1) continue;
...如果您愿意...
虽然易于编写、简洁且有时很有帮助,但与布尔版本相比,这些可能更难优化 - 如果您关心的话,请进行基准测试。
另一种有时有用的方法:
for (const auto & rule_pair : rule_index)
if (&rule_pair != &*std::begin(rule_index))
{
...
}
在使用 auto
的 for
循环中,迭代器迭代 unordered_map
。像这样:
using RuleIndex = std::unordered_map<uint, Symbol*>;
RuleIndex rule_index;
for(const auto & rule_pair : rule_index ) {
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
假设所有变量都已正确定义,因为代码运行良好。我的问题是,如何排除第一次迭代?例如,地图包含 3 行,当前循环迭代 0、1、2。我只想迭代 1 和 2。
bool is_first_iteration = true;
for(const auto & rule_pair : rule_index) {
if (std::exchange(is_first_iteration, false)) continue;
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
std::exchange
调用将 false
分配给 is_first_iteration
和 returns 先前的值。这实际上是 the paper proposing std::exchange
for C++14 中讨论的用例之一。该论文还展示了一个参考实现,如果您坚持使用 C++11,则可以使用它。
如果您不能使用 std::exchange(由于 C++11 的限制),这个简单的解决方案也可以工作:
bool is_first_iteration = true;
for (const auto & rule_pair : rule_index)
{
if (is_first_iteration)
{
is_first_iteration = false;
continue;
}
std::cout << rule_pair.first << ": ";
printList(rule_pair.second, 0);
std::cout << std::endl;
}
我有时使用的一个简洁的 C++11 选项,它也保留了一个有时很方便的计数器。我在下面展示了 if (i++)
,它依赖于 0
转换为 false
,而其他数字转换为 true
,但如果你是,你可以输入 if (++i > 1)
更舒服:
size_t i = 0;
for (const auto & rule_pair : rule_index)
if (i++)
{
...
}
...或if (++i == 1) continue;
...如果您愿意...
虽然易于编写、简洁且有时很有帮助,但与布尔版本相比,这些可能更难优化 - 如果您关心的话,请进行基准测试。
另一种有时有用的方法:
for (const auto & rule_pair : rule_index)
if (&rule_pair != &*std::begin(rule_index))
{
...
}