2017-02-17 8 views
0

これは私のattempt私はこれを間違ってバインドしていますか?

#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; 
} 

私は後で機能のいずれかの種類を渡すことができ、ボイスアップデータ「基本」イテレータの並べ替えを作成します。それはすべての声を繰り返し、私はその繰り返しに必要な機能を渡します。

しかし、私はOscillator::ModulatePitchの機能をアップデータに渡すのに間違っているようですか?

ここで私は間違っていますか?

+1

ラムダの使用は許可されていますか? 'auto callback = [pOscillator](auto&voice、double d){return pOscillator-> ModulatePitch(voice、d);}を使用します。 }; '私のために働く。一般的な経験則は、lambdasを使うことができるときに 'std :: bind'を避けることです。 – Maikel

+1

'std :: bind'をlambdasに置き換えることを考えましたか? – nwp

+1

'callback'に明示的な型を使用すると修正されます。 'std :: function コールバック= ...' 私は理由を正確には説明できません。 – pergy

答えて

0

pergyさんがコメントに書いているとおり、autoの代わりにstd::function<double(Voice &, double)> callback = ...を使用すると、それが動作します。理由は、bindオブジェクトからstd::functionへの変換を強制するからです。

あなたは

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(); 

を行う場合は、返却型が貴様していることがわかります。そして、この場合、2番目のbindは、2番目の型を使用してオブジェクトを構築しようとします(これは動作しません)。私は、外部バインドによって呼び出されていない変換演算子(バインドからstd :: function)に問題があると思う。

関連する問題