2016-03-04 76 views
1

我想避免有兩個參數。因此,我們有:C++ :: Template函數 - 從object.function獲取對象的地址

class A; 
void A::boo(); 

我希望把這個代碼:

template <class C> 
void foo(C &c, void (C::*func)()) 
{ 
    (c.*func)(); 
} 

A a; 
foo(a, &a.boo); 

要這樣:

template <class C, C &c>  // Something similar 
void foo(void (C::*func)()) 
{ 
    (c.*func)(); 
} 

A a; 
foo(&a.boo);     // Since I'm using the reference of the object instance 

我相信我的理解是,在C++模板是簡單的字符串替換,但我觀察它們的實現稍微先進和靈活。我也相信我掌握了階級及其成員職能的概念;函數的內存中有一個地址,類實例就像函數的參數,以訪問該類實例的內存成員。

所以,讓這一切成爲現實,是否有辦法做我想做的事情?

編輯:

我不好,錯過了&跡象。更正:& a.boo

+2

C++模板無處不接近簡單的字符串替換。在你的例子中'foo'應該從哪裏得到'c'?你期望通過它作爲模板參數嗎? – TartanLlama

+0

而'foo(a,a.boo)'不應該編譯。你是不是指'foo(a,&A :: boo)'? – TartanLlama

+1

C++有時很麻煩:你總是需要對象和成員函數指針! –

回答

0

這不是C++的工作方式。當你傳遞一個函數時,你確實通過了它的地址。所以,如果A::foo是靜態的還是非虛,它的地址是類的所有對象(和子類)A.

即使是虛擬的一樣,你將有foo每個子類一個實例,和兩個不同的對象相同的子類將具有相同的地址foo

這意味着,即使您編寫了a.foo,在運行時也無法找到您使用的對象:所有對a的引用都沒有了。

唯一可能的方法 - 但請注意我是而不是建議使用它,因爲可能存在角落案例 - 將使用宏,因爲它們是在編譯時執行的。類似於

#define FOO(a,b) foo(a, a.b) 

可能允許保留對編譯時給出的對象的引用。

TL/DR:C++不支持用於綁定方法的Python語法...

2

最簡單的是接受函子將綁定實例的號召:

template <class F> 
void foo(F f) 
{ 
    f(); 
} 

A a; 
foo([&a](){ a.boo(); }); 

或者,如果沒有拉姆達:

A a; 
foo(std::bind(&A::boo, &a));