簡體   English   中英

如何在 C++ 中將函數傳遞給 Class?

[英]How To Pass Functions To Class In C++?

So I have been working on an Arduino program that sends MIDI data over USB, and I can't seem to figure out how to pass the function that handles sending of midi data to my main class. 它在某些時候有效,但由於某種原因,它沒有,而且我覺得我已經嘗試了各種組合。

這是我的主文件,簡化為 output 串行 MIDI 數據:

#include "XiaoPiezoDrum.h"

void sendNoteOn(int note, int velocity, int chan) {
    Serial.printf("WORKS! %d %d %d\n", note, velocity, chan);
};

XiaoPiezoDrum drum(9, 2, 3, 4);

void setup() {
    drum.setNoteComFunctions(sendNoteOn);
}

這是setNoteComFunctions方法的樣子:

void XiaoPiezoDrum::setNoteComFunctions(const std::function<void(int, int, int)>& onFunc) {
    sendNote = [onFunc](auto && PH1, auto && PH2, auto && PH3) { onFunc(PH1, PH2, PH3); };
}

這里是主要 class 定義的相關部分:

class XiaoPiezoDrum {
public:
    XiaoPiezoDrum();
    XiaoPiezoDrum(int piezoPin, int rPin, int gPin, int bPin);
    void setNoteComFunctions(const function<void(int, int, int)>& onFunc); 
    void RunCycle();

private:
    std::function<void(int, int, int)> sendNote;
}

所以一切都運行得很好,直到我從RunCycle 中調用 sendNote 這只是在每個循環中調用,然后串行通信突然停止。 我究竟做錯了什么? 我還嘗試使用 bind 而不是 lambda,同樣的事情發生了。 當我只是將主文件中sendNoteOn中的相同打印語句復制到 setNoteComFunctions 中的lambda中時,它打印得很好,所以我知道問題在於從主文件鏈接 function 。

我嘗試過的事情:

  • 在 setNoteComFunctions 中傳遞function作為參考而不是
  • 使用綁定而不是 lambda
  • 更改sendNoteOn的正文
  • 制作 lambda arguments 參考
  • 使 lambda arguments 不參考
  • 在 lambda 中返回onFunc

幾個小時以來,我一直在用頭撞鍵盤。 如果有人知道我做錯了什么,我希望得到一個解釋!

編輯這是RunCycle的完整代碼。 其中許多變量是我在提供的 class 定義中遺漏的實例變量,但我知道問題出在sendNote的調用上,因為如果我將其注釋掉,事情將繼續正常運行。 我也試過用固定的 integer 替換速度變量,同樣的事情發生了。

void XiaoPiezoDrum::RunCycle() {
    double val = sensor.read();
    val = (val > 0) ? val : 0;
    Serial.println(val);
    unsigned long timeElapsed;
    int velocity;
    MaxVal = (val > MaxVal) ? val : MaxVal;
    trigger = val > THRESHOLD && !triggering;
    if (val > THRESHOLD && !triggering) trigger = true;
    if (trigger) {
        triggerTime = millis();
        trigger = false;
        triggering = true;
        triggerBuffer.clear();
    }
    if (triggering) {
        timeElapsed = millis() - triggerTime;
        if (timeElapsed < SAMPLE_TIME) {
            loopCounter++;
            triggerBuffer.addValue(val);
            Serial.println(val);
        }
        else {
            velocity = map(round(triggerBuffer.getMax()), 0, 300, THRESHOLD, 127);
            Serial.printf("Velocity: %d\n", velocity);
            if (comFunctionsSet) sendNote(40, velocity, 1);
            noteEndTime = millis();
            triggerTime = 0;
            triggerBuffer.clear();
            triggering = false;
            resting = true;
        }
    }
}

jignatius的回答做到了! 我早該知道我能做到的!! 謝謝!

我只需要更換

void XiaoPiezoDrum::setNoteComFunctions(const std::function<void(int, int, int)>& onFunc) {
    sendNote = [onFunc](auto && PH1, auto && PH2, auto && PH3) { onFunc(PH1, PH2, PH3); };
}

和:

void XiaoPiezoDrum::setNoteComFunctions(const std::function<void(int, int, int)>& onFunc) {
    sendNote = onFunc;
}

很高興解決了這個問題! 謝謝!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM