提问人:Nikita Rudenko 提问时间:2/9/2020 最后编辑:Nikita Rudenko 更新时间:2/9/2020 访问量:127
shift::bimap 中的值
Shift values in boost::bimap
问:
我有一个无序的双映射,如下所示:
using SymPressMap =
boost::bimap<boost::bimaps::unordered_set_of<sym>,
boost::bimaps::unordered_set_of<Press>>;
这基本上是“sym”和“Press”之间的双射。我想循环“Presses”的子集,如图片所示:bimap 状态前后
以下是使用 std::unordered_map 编译但使用 bimap 失败的算法:
void Layout::cycle(SymVector syms) {
assert(syms.size() >= 2);
for (auto it = syms.rbegin(); it != syms.rend() - 1; it++) {
std::swap(sympressmap.left.at(*it), sympressmap.left.at(*(it + 1)));
}
}
其基本思想是连续交换相邻的(以“符号”为单位)元素。但是我收到此错误:
Error C2678 binary '=': no operator found which takes a left-hand operand of type '_Ty' (or there is no acceptable conversion)
KeyboardOptimizer c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.16.27023\include\utility 68
所以,问题是如何在 bimap 中交换两个元素?
UPD:擦除插入版本,感谢 John Zwinck,它编译
void Layout::cycle(SymVector syms) {
assert(syms.size() >= 2);
Press plast = pressmap.left.at(*syms.rbegin());
pressmap.left.erase(*syms.rbegin());
for (auto it = syms.rbegin() + 1; it != syms.rend(); it++) {
auto p = pressmap.left.at(*it);
pressmap.left.erase(*it);
pressmap.left.insert(SymPressMap::left_value_type(*(it - 1), p));
}
pressmap.left.insert(SymPressMap::left_value_type(*syms.begin(), plast));
}
答:
1赞
John Zwinck
2/9/2020
#1
使用常规unordered_map,交换值没有问题,因为容器结构不依赖于它们。但是,修改键是一个常见的困难和混乱领域,因为键定义了容器的结构(哪些值放在哪些存储桶中)。mapped_type
key_type
你在这里有同样的问题,那就是你试图修改存储在容器中的键(你是在交换值方面这样做的,但在双映射中,键和值当然是对偶的)。你不能这么做。您可以做的是复制键值对,交换其值,从容器中删除原始值对,然后插入修改后的键值对。
评论
0赞
Nikita Rudenko
2/9/2020
谢谢。但是,如果无序双映射基于两个映射,则交换可以更有效:只需交换两个映射中的值
0赞
John Zwinck
2/10/2020
一个的value_type将是另一个的mapped_type,因此通常无法交换它们(在您的示例用例中也是如此)。
0赞
Nikita Rudenko
2/10/2020
当 bimap 基于两个映射时,无需移位键:在第一个映射值中顺时针移动,在第二个映射值中逆时针移动。因此,钥匙“停留”在它们的位置。
评论