2016-03-04 75 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));