2016-09-15 83 views
2

我有許多與它們各自的類對象綁定函數指針:解除綁定的std ::結合在C++

ExampleClass EO; 
std::function<void()> Example=std::bind(&ExampleClass::ExampleFunction, &EO); 

然而,我想「解除綁定」這些在以後,具體地,以確定每個'std :: function都涉及到的具體類。

auto Unbind(std::function<void()> &Example)->void 
{ 
    //Find which object &Example is bound with (in this case EO/ExampleClass) 
} 

這樣做的最好方法是什麼?

+3

這是不可能的。雖然你可以檢索一個'std :: function'的目標,但是目標類型是綁定表達式的不可知類型,它沒有一個接口來檢索你之後的信息。 –

+0

@KerrekSB這是一個答案:) – Quentin

+0

@KerrekSB你可以提供一個示例使用std :: function :: target嗎? –

回答

4

std::function執行類型擦除。按照名稱,它將從界面中清除真實的底層類型。

有沒有辦法從那裏回來。

如果要保留目標對象的類型,然後std::mem_fn可能是你想要什麼:

http://en.cppreference.com/w/cpp/utility/functional/mem_fn

+0

'target'的確從類型擦除中提供了一個「回頭路」。問題是'std :: bind'。 –

+0

@KerrekSB target_type雖然是一個'std :: type_info',不是一個類型。因此,它唯一可用於與預先計算的已知類型列表進行比較。我認爲它不符合我的意思(即可推論)的意思。我會接受它是「回來的路上的一步」:) –

+1

嗯,是的,你需要知道你期待的類型,但要清楚,'target'(而不是'target_type')返回一個實際的指向真實對象(或null)。 –

1

你不能用一個function對象做到這一點。

一種可能性是構造一個包裝器,在其中存儲對方法和對象的引用。

事情是這樣的:

template<typename T, typename Fn> 
struct MemberFunctionPointer { 
    MemberFunctionPointer(T* ref, Fn fn) : m_ref(ref), 
              m_method(fn) { } 

    template<typename... Args> 
    auto operator()(Args&&... args) { 
    return (m_ref->*m_method)(std::forward<Args...>(args)...); 
    } 

    T* m_ref = nullptr; // a reference (pointer) to the object instance 
    Fn m_method = nullptr; // a reference to the function method 
}; 

注:這只是擦傷。您應該添加更復雜的界面。此外,創建對象的幫助函數也可能很有用。

您可以傳遞那種對象而不是簡單的function

struct Foo { 
    void bar() { 
    // something 
    } 
}; 

int main(int argc, char *argv[]) { 
    Foo f; 
    MemberFunctionPointer<Foo, decltype(&Foo::bar)> method(&f, &Foo::bar); 

    method(); // call the method on the object f. 

    assert(&f == method.get_obj_reference()); 
    return 0; 
}