2017-02-16 44 views
0

Here's my code如何在綁定函數中「自動發送」調用對象的實例?

#include <iostream> 
#include <functional> 
#include <vector> 

class Voice 
{ 
public: 
    double mVoiceValue = 0.0; 
    std::function<double(Voice &, double)> mTargetFunction; 

    Voice(std::function<double(Voice &, double)> targetFunction) : mTargetFunction(targetFunction) { } 
    ~Voice() { }  

private: 
}; 

class Osc 
{ 
public: 
    double mOscValue = 1.0; 

    Osc() { } 
    ~Osc() { } 

    double Modulate(Voice &voice, double value) { 
     return mOscValue * voice.mVoiceValue * value; 
    } 

private: 
}; 

int main() 
{ 
    Osc *osc = new Osc(); 
    Voice voice1(std::bind(&Osc::Modulate, osc, std::placeholders::_1, std::placeholders::_2)); 
    Voice voice2(std::bind(&Osc::Modulate, osc, std::placeholders::_1, std::placeholders::_2)); 

    voice1.mVoiceValue = 1.0; 
    voice2.mVoiceValue = 2.0; 
    std::cout << "value: " << voice1.mTargetFunction(voice1, 10.0) << std::endl; 
    std::cout << "value: " << voice2.mTargetFunction(voice2, 100.0) << std::endl; 
} 

我想非傳遞voice1/voice2實例(即本身)到調用bind函數。因爲我想直接發送該實例,因爲它與調用對象相同。

如何以這種方式進行綁定?

即它必須返回相同的結果調用:

std::cout << "value: " << voice1.mTargetFunction(10.0) << std::endl; 
std::cout << "value: " << voice2.mTargetFunction(100.0) << std::endl; 
+0

在'Voice'上提供一個調用'mTargetFunction(* this,whatever);'的方法。然後把它叫做'voice1.callTarget(10.0);' –

+1

請注意,當你綁定時你會創建兩個'osc'對象。 – Slava

+0

@Slava:你是什麼意思「你製作2份osc」? – markzzz

回答

0

如果它的好了Voice構造方法來參數(在Osc對象和成員函數指針)可以解決這個問題是這樣的:

class Voice 
{ 
public: 
    double mVoiceValue = 0.0; 
    std::function<double(double)> mTargetFunction; 

    template<typename T, typename F> 
    Voice(T& targetObject, F&& targetFunction) 
     : mTargetFunction(std::bind(targetFunction, targetObject, std::ref(*this), std::placeholders::_1)) { } 
    ~Voice() { } 
}; 

class Osc 
{ 
public: 
    double mOscValue = 1.0; 

    Osc() { } 
    ~Osc() { } 

    double Modulate(Voice &voice, double value) { 
     return mOscValue * voice.mVoiceValue * value; 
    } 
}; 

... 

Osc osc; 
Voice voice1(osc, &Osc::Modulate); 
Voice voice2(osc, &Osc::Modulate); 

voice1.mVoiceValue = 1.0; 
voice2.mVoiceValue = 2.0; 
std::cout << "value: " << voice1.mTargetFunction(10.0) << std::endl; 
std::cout << "value: " << voice2.mTargetFunction(100.0) << std::endl; 

這裏最重要的一點是std::refVoice參數的用法。

如果它始終是要被稱爲Modulate成員函數,那麼Voice構造不必帶指針的成員函數作爲參數,然後使用&T::Modulate在調用std::bind

+0

我不想使用模板。 – markzzz

+0

@paizza然後,除非你總是*使用'Osc',否則你別無選擇:無論是你的解決方案還是我的解決方案。你只*使用'Osc'對象,然後進行前向聲明並對其使用進行硬編碼。可以爲'Voice'構造函數創建多個重載,每個重載都爲每個可能使用的對象提供一個指向成員函數的指針。 –

+0

你是什麼意思,「你將永遠使用Osc」?我想爲每個聲音使用osc的'Osc :: Modulate'功能。奴隸說:「請注意,你綁定時會製作2個osc對象副本。」不確定他的意思。也許它的相關? – markzzz

相關問題