简体   繁体   English

投射由迭代器指向的对象

[英]Cast an object that is pointed by an iterator

I have this multiset container: 我有这个多集容器:

multiset<IMidiMsgExt, IMidiMsgExtComp> queuedNotes;

IMidiMsgExt is a struct I've created myself (I need it for one additional property, mTick ) that extend IMidiMsg : IMidiMsgExt是我创建的结构(扩展IMidiMsg ,我需要一个附加属性mTick ):

struct IMidiMsgExt : public IMidiMsg
{
    IMidiMsgExt() {
    }

    double mTick = 0.;

    void IMidiMsgExt::MakeNoteOnMsg(int noteNumber, int velocity, int offset, double tick, int channel)
    {
        Clear();
        mStatus = channel | (kNoteOn << 4);
        mData1 = noteNumber;
        mData2 = velocity;
        mOffset = offset;
        mTick = tick;
    }

    void IMidiMsgExt::MakeNoteOffMsg(int noteNumber, int offset, double tick, int channel)
    {
        Clear();
        mStatus = channel | (kNoteOff << 4);
        mData1 = noteNumber;
        mOffset = offset;
        mTick = tick;
    }

    void IMidiMsgExt::Clear()
    {
        mOffset = 0;
        mStatus = mData1 = mData2 = 0;
        mTick = 0.;
    }
};

Next: I store in that queuedNotes multiset some IMidiMsgExt objects, with: 下一步:我将一些IMidiMsgExt对象存储在该queuedNotesIMidiMsgExt ,其内容如下:

IMidiMsgExt* noteOff = new IMidiMsgExt;
noteOff->MakeNoteOffMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(*noteOff);

Now, I need to use a function called SendMidiMsg(IMidiMsg* pMsg) (that takes IMidiMsg type as input) sending my object IMidiMsgExt to it. 现在,我需要使用一个名为SendMidiMsg(IMidiMsg* pMsg)的函数(以IMidiMsg类型作为输入),将对象IMidiMsgExt发送给它。

I extract the first object from my list to an iterator: 我将列表中的第一个对象提取到迭代器中:

auto midiMessage = queuedNotes.begin();

But when I try to cast it and use SendMidiMsg : 但是当我尝试投射它并使用SendMidiMsg

SendMidiMsg((IMidiMsgExt*)midiMessage);

it says no suitable conversion function from "std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<IMidiMsgExt>>>" to "IMidiMsg *" exists 它表示no suitable conversion function from "std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<IMidiMsgExt>>>" to "IMidiMsg *" exists

Where am I wrong? 我哪里错了? Should I use dynamic casting ? 我应该使用dynamic casting吗?

auto midiMessage = queuedNotes.begin();

midiMessage is of type std::multiset::iterator . midiMessage类型为std::multiset::iterator And it is not convertable to your type IMidiMsgExt . 而且它不能转换为您的IMidiMsgExt类型。 Iterator is an object that behaves similarly to a pointer, so you can use dereference operator ( * ) to get the object that it "points to". 迭代器是一个行为类似于指针的对象,因此您可以使用取消引用运算符( * )获取其“指向”的对象。 You also don't need to cast derived object to its base, that is done implicitly. 您也不需要将派生对象强制转换为其基础,这是隐式完成的。 All you need to do is get the address of where the iterator "points to" to get a pointer to IMidiMsgExt : 您需要做的就是获取迭代器“指向”的地址,以获取指向IMidiMsgExt的指针:

SendMidiMsg(&*midiMessage);

A quick break down of &*midiMessage : &*midiMessage快速分解:

  variable    -     type
midiMessage   - std::multiset::iterator
*midiMessage  - IMidiMsgExt
&*midiMessage - IMidiMsgExt*

Edit: About your const_iterator error. 编辑:关于您的const_iterator错误。 std::multiset::begin() is supposed to always return const_iterator . std :: multiset :: begin()应该总是返回const_iterator Your function SendMidiMsg() wants a non const pointer - it is saying it wants to edit the message. 您的函数SendMidiMsg()一个非const指针-表示要编辑消息。 multiset does not allow changing the elements. multiset不允许更改元素。

You can copy the message and then call SendMidiMsg() . 您可以复制消息,然后调用SendMidiMsg() If you don't need the message inside the container anymore, you can also erase it afterwards. 如果您不再需要该消息在容器内,则以后也可以将其删除。

auto msg = *midiMessage;
SendMidiMsg(&msg);
queuedNotes.erase(midiMessage);

Note: It seems like you have a memory leak in the program. 注意:程序似乎有内存泄漏。 You create messages with new and I don't see any calls to delete, to release the memory. 您使用new创建消息,但看不到有任何删除或释放内存的调用。

IMidiMsgExt* noteOff = new IMidiMsgExt;
noteOff->MakeNoteOffMsg(57, 0, tickSize * 111, 0);
queuedNotes.insert(*noteOff);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM