我需要更改多重集的“键”:
multiset<IMidiMsgExt, IMidiMsgExtCompByNoteNumber> playingNotes;
例如当我使用 .find()
时它的功能是搜索并返回带有 NoteNumber
的第一个对象(迭代器)适当的值(value)。
我说“第一”是因为我的多重集列表可能包含具有相同“键”的对象。所以我做了:
struct IMidiMsgExtCompByNoteNumber {
bool operator()(const IMidiMsgExt& lhs, const IMidiMsgExt& rhs) {
return lhs.NoteNumber() < rhs.NoteNumber();
}
};
但是当我尝试这样做时:
auto it = playingNotes.find(60);
编译器说 no instance of overloaded function "std::multiset<_Kty, _Pr, _Alloc>::find [with _Kty=IMidiMsgExt, _Pr=IMidiMsgExtCompByNoteNumber, _Alloc=std::allocator<IMidiMsgExt>]" matches the argument list
我是不是误解了整件事?怎么了?
最佳答案
我相信你对这里有一些误解:
- associative container 的一部分的类型是它的键类型和比较器。因为 C++ 是强类型的,所以更改容器上的比较器的唯一方法是创建一个新容器,将所有元素复制或移动到其中
- 创建容器中所有元素的拷贝可能是一个代价高昂的过程
- 创建拷贝即违反了 Single Source of Truth最佳实践
-
multiset
很少用,职业生涯用过一次,别人指出了不足,推荐给大家use another container , write your own container ,或者就我而言,我建议只使用vector
并在必要时按您想要的方式对其进行排序
我将对您的评论进行分类以展示如何 the answer I've already given you是正确的:
- 我们假设
multiset<IMidiMsgExt, IMidiMsgExtCompByNoteNumber>
您选择的是必需的,无法使用vector
进行改进如 4 中所建议,其中:
struct IMidiMsgExtCompByNoteNumber {
bool operator()(const IMidiMsgExt& lhs, const IMidiMsgExt& rhs) {
return lhs.NoteNumber() < rhs.NoteNumber();
}
};
- 您不能使用
multiset::find
因为这需要您指定确切的IMidiMsgExt
您正在寻找;所以你需要使用find_if(cbegin(playingNotes), cend(playingNotes), [value = int{60}](const auto& i){return i.mNote == value;})
搜索特定属性值。在PlayingNotes
上直接使用哪个会很好不改变排序,因为you say :
I want to delete the first note that has mNote of 60. No matter the mTime when deleting.
The first element find will find for that, erase. [sic]
- 我会将答案中的代码滚动到一个函数中,因为 you say :
Ill recall find if I want another element, maybe with same value, to get deleted [sic]
您的最终解决方案应该是编写如下函数:
bool foo(const multiset<IMidiMsgExt, IMidiMsgExtCompByNoteNumber>& playingNotes, const int value) {
const auto it = find_if(cbegin(playingNotes), cend(playingNotes), [=](const auto& i){return i.mNote == value;});
const auto result = it != cend(playingNotes);
if(result) {
playingNotes.erase(it);
}
return result;
}
你会这样调用它:foo(playingNotes, 60)
如果你想知道一个元素是否被删除,你可以测试 foo
的返回。
关于c++ - Comparator 可以用来设置新的 key ,不是吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36920853/