检测迭代器是否是 std::map 的最后一个元素
Detect if iterator is last element of std::map
这与 this question 相似,但不是重复的。我正在尝试遍历地图并打印每个元素的值,但最后一个元素的输出略有不同。在那个问题中,他们建议使用 map.rbegin().base()
,但它对我不起作用。
这是我的代码:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
for (auto iter = charMap.begin(); iter != charMap.end(); iter++)
{
std::cout << iter->first << ":\t" << iter->second;
if (iter == charMap.rbegin().base())
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
}
}
我希望我的输出看起来像这样:
a: 1
b: 2
c: 3
d: 4 //This is the last element.
但是,我得到了这个输出:
a: 1
b: 2
c: 3
d: 4
现在我意识到有更好的方法可以做到这一点,但我希望它也能起作用。为什么我不能比较 iter
和 charMap.rbegin().base()
?
丑。 . .但 。 . .
auto iterCpy = iter;
if (++iterCpy == charMap.end())
std::cout << "\t//This is the last element.\n";
使用 vsoftco 的回答:)
将 <iterator>
中的 std::next
用作
if (std::next(iter) == charMap.end())
std::cout << "\t//This is the last element.\n";
相反。
base()
方法 returns 指向一个元素的迭代器,该元素跟在反向迭代器指向的元素之后。这意味着 rbegin().base()
等同于 end()
要完成您的任务,您可以这样做:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
for (auto iter = charMap.begin(); iter != charMap.end(); )
{
std::cout << iter->first << ":\t" << iter->second;
if (++iter == charMap.end())
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
}
}
base()
不 return 相同的元素:
The base iterator refers to the element that is next (from the std::reverse_iterator::iterator_type perspective
) to the element the reverse_iterator
is currently pointing to. That is &*(rit.base() - 1) == &*rit
.
这按预期工作:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
auto last = charMap.rbegin();
++last;
for (auto iter = charMap.begin(); iter != charMap.end(); iter++)
{
std::cout << iter->first << ":\t" << iter->second;
if (iter == last.base())
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
}
}
因为std::reverse_iterator
存储偏移量为1
的迭代器,所以charMap.rbegin().base() == charMap.end()
。 here 上的图表说明了这一点。
您应该改用 std::prev
或 std::next
来自 <iterator>
:
iter == std::prev(charMap.end())
或
std::next(iter) == charMap.end()
你觉得哪个更有意义。
实际上,这不会起作用,因为 iter
确实不同于 charMap.rbegin().base()
。
你的逻辑是正确的,唯一的问题是 charMap.rbegin().base()
迭代器等于 charMap.end()
,但是你在 iter
到达 charMap.end()
的时候离开你的 for 语句] 值,所以它永远没有机会在 for 循环内的 if 语句中测试它。
要使其正常工作,您可以按以下方式重写 if 语句:
if (iter->first == charMap.rbegin()->first)
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
因此您将比较映射键而不是迭代器本身。
这是有效的:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
for (auto iter = charMap.begin(); ;)
{
std::cout << iter->first << ":\t" << iter->second;
if (++iter== charMap.end()){
std::cout << "\t//This is the last element.\n"; break;
}
else
std::cout << "\n";
}
}
这与 this question 相似,但不是重复的。我正在尝试遍历地图并打印每个元素的值,但最后一个元素的输出略有不同。在那个问题中,他们建议使用 map.rbegin().base()
,但它对我不起作用。
这是我的代码:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
for (auto iter = charMap.begin(); iter != charMap.end(); iter++)
{
std::cout << iter->first << ":\t" << iter->second;
if (iter == charMap.rbegin().base())
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
}
}
我希望我的输出看起来像这样:
a: 1
b: 2
c: 3
d: 4 //This is the last element.
但是,我得到了这个输出:
a: 1
b: 2
c: 3
d: 4
现在我意识到有更好的方法可以做到这一点,但我希望它也能起作用。为什么我不能比较 iter
和 charMap.rbegin().base()
?
丑。 . .但 。 . .
auto iterCpy = iter;
if (++iterCpy == charMap.end())
std::cout << "\t//This is the last element.\n";
使用 vsoftco 的回答:)
将 <iterator>
中的 std::next
用作
if (std::next(iter) == charMap.end())
std::cout << "\t//This is the last element.\n";
相反。
base()
方法 returns 指向一个元素的迭代器,该元素跟在反向迭代器指向的元素之后。这意味着 rbegin().base()
等同于 end()
要完成您的任务,您可以这样做:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
for (auto iter = charMap.begin(); iter != charMap.end(); )
{
std::cout << iter->first << ":\t" << iter->second;
if (++iter == charMap.end())
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
}
}
base()
不 return 相同的元素:
The base iterator refers to the element that is next (from the
std::reverse_iterator::iterator_type perspective
) to the element thereverse_iterator
is currently pointing to. That is&*(rit.base() - 1) == &*rit
.
这按预期工作:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
auto last = charMap.rbegin();
++last;
for (auto iter = charMap.begin(); iter != charMap.end(); iter++)
{
std::cout << iter->first << ":\t" << iter->second;
if (iter == last.base())
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
}
}
因为std::reverse_iterator
存储偏移量为1
的迭代器,所以charMap.rbegin().base() == charMap.end()
。 here 上的图表说明了这一点。
您应该改用 std::prev
或 std::next
来自 <iterator>
:
iter == std::prev(charMap.end())
或
std::next(iter) == charMap.end()
你觉得哪个更有意义。
实际上,这不会起作用,因为 iter
确实不同于 charMap.rbegin().base()
。
你的逻辑是正确的,唯一的问题是 charMap.rbegin().base()
迭代器等于 charMap.end()
,但是你在 iter
到达 charMap.end()
的时候离开你的 for 语句] 值,所以它永远没有机会在 for 循环内的 if 语句中测试它。
要使其正常工作,您可以按以下方式重写 if 语句:
if (iter->first == charMap.rbegin()->first)
std::cout << "\t//This is the last element.\n";
else
std::cout << "\n";
因此您将比较映射键而不是迭代器本身。
这是有效的:
#include <iostream>
#include <map>
int main()
{
std::map <char, int> charMap = { {'a', 1}, {'b', 2}, {'c', 3}, {'d', 4} };
for (auto iter = charMap.begin(); ;)
{
std::cout << iter->first << ":\t" << iter->second;
if (++iter== charMap.end()){
std::cout << "\t//This is the last element.\n"; break;
}
else
std::cout << "\n";
}
}