2017-02-17 5 views
0

Das ist mein attempt:Wo bin ich falsch das bindend?

#include <iostream> 
#include <functional> 

class Voice; 

class EnvelopeMultiPoints 
{ 
public: 
    std::function<double(Voice &, double)> mCallback; 

    void SetupModulation(std::function<double(Voice &, double)> callback, int paramID) { 
     mCallback = callback; 
    } 
}; 

class Voice 
{ 
public: 
    EnvelopeMultiPoints mEnvelopeMultiPoints; 
}; 

class VoiceManager 
{ 
public: 
    Voice mVoices[16]; 

    inline void UpdateVoices(std::function<void(Voice &)> callback) { 
     for (int i = 0; i < 16; i++) { 
      callback(mVoices[i]); 
     } 
    } 
    static void SetupEnvelopeMultiPointsModulation(Voice &voice, std::function<double(Voice &, double)> callback, int paramID) { 
     voice.mEnvelopeMultiPoints.SetupModulation(callback, paramID); 
    } 
}; 

class Oscillator 
{ 
public: 
    double ModulatePitch(Voice &voice, double currentValue) { 
     // somethings with voice 
     return currentValue * 10.0; 
    } 
}; 

int main() 
{  
    VoiceManager voiceManager; 
    Oscillator *pOscillator = new Oscillator(); 

    int param = 100; 
    auto callback = std::bind(&Oscillator::ModulatePitch, pOscillator, std::placeholders::_1, std::placeholders::_2); 
    voiceManager.UpdateVoices(std::bind(&VoiceManager::SetupEnvelopeMultiPointsModulation, std::placeholders::_1, callback, param));  

    Voice voice = voiceManager.mVoices[0]; 
    std::cout << voice.mEnvelopeMultiPoints.mCallback(voice, 1.0) << std::endl; 

    delete pOscillator; 
} 

ich eine Art von Voice-Updater „basic“ Iterator, die ich später jede Art von Funktionen weitergeben kann. Es iteriert alle Stimmen und übergibt die Funktion, die ich für diese Iteration benötige.

Aber es scheint, ich bin falsch bei der Bindung die Oscillator::ModulatePitch Funktion an den Updater übergeben?

Wo liege ich hier falsch?

+1

dürfen Sie lambdas verwenden? Verwenden von 'auto callback = [pOscillator] (auto & Sprache, double d) {Return pOscillator-> ModulatePitch (Stimme, d); }; 'funktioniert für mich. Eine allgemeine Faustregel besteht darin, 'std :: bind 'zu vermeiden, wenn Sie lambdas verwenden können. – Maikel

+1

Haben Sie erwogen, 'std :: bind 'durch Lambdas zu ersetzen? – nwp

+1

Verwendung von expliziten Typ für 'Callback' wird es beheben. 'std :: funktion callback = ...' Aber ich kann nicht genau Grund warum :) – pergy

Antwort

0

Wie pergy schrieb in seinem Kommentar, wenn Sie std::function<double(Voice &, double)> callback = ... anstelle von auto verwenden, funktioniert es. Der Grund ist, dass es eine Konvertierung von einem bind-Objekt zu einem std::function erzwingt.

Wenn Sie das tun

auto callback1 = std::bind(&Oscillator::ModulatePitch, pOscillator, std::placeholders::_1, std::placeholders::_2); 
std::function<double(Voice &, double)>callback2 = std::bind(&Oscillator::ModulatePitch, pOscillator, std::placeholders::_1, std::placeholders::_2); 
std::cout << typeid(callback1).name(); 
std::cout << typeid(callback2).name(); 

Sie werden sehen, dass die zurückkehrenden Arten differents sind. Und in diesem Fall versucht das zweite bind, sein Objekt mit dem zweiten Typ zu erstellen (was nicht funktioniert). Ich denke, es gibt ein Problem mit dem Konvertierungsoperator (von bind zu std :: function), der nicht von der externen Bindung aufgerufen wird.

Verwandte Themen