我想将一个方法作为参数传递给一个接受int并返回void的方法:
test()
在Error 1 error C2664: cannot convert parameter 1 from 'void (__thiscall B::* )(int)' to 'void (__cdecl *)(int)'
内我收到此错误:
Document
+----+---------------+-----------------+
| id | name | description |
+----+---------------+-----------------+
| 1 | BriefDocument | Something |
+----+---------------+-----------------+
DocumentData
+----+--------------+-----------------+--------------+
| id | key | value | documentId |
+----+--------------+-----------------+--------------+
| 1 | whatData | inputted data | 1 |
+----+--------------+-----------------+--------------+
| 2 | whoData | inputted data | 1 |
+----+--------------+-----------------+--------------+
| 3 | whyData | inputted data | 1 |
+----+--------------+-----------------+--------------+
| 4 | howData | inputted data | 1 |
+----+--------------+-----------------+--------------+
我在StackOverflow上看到了一些如何解决这个问题的例子,但它使用了C ++ 11中我无法访问的元素。
如何使用C ++ 03解决这个问题?
答案 0 :(得分:4)
您不能将非静态方法传递给带有指向函数的指针的函数。功能和方法是两个完全不同的东西。为了调用非静态方法,显然你必须拥有一个你正在调用它的方法的对象。
如果在您的示例中Done()
是静态类方法,那么,是的,您可以通过这种方式传递它,因为静态类方法只是函数的另一个名称。
可以有一个指向类方法的指针:
void A::SetCallback(void (B::*callback)(int))
{
}
void B::test()
{
a->SetCallback(&B::Done); //
}
void B::Done(int i)
{
..........................
}
但是为了调用类方法,你需要一个调用方法的对象:
B *object=give_me_a_pointer_to_b_from_somewhere();
(object->*callback)(0);
答案 1 :(得分:2)
&ClassName::method_name
创建指针,void(ClassName::*)(int, char*)
是类型。
void go(void(ClassName::*parameter_name)(int, char*));
go(&ClassName::method_name);
答案 2 :(得分:1)
您不能将指向类方法(在您的情况下为void (B::*) (int)
类型)的指针传递给指向自由函数的指针。
如果可以,会发生什么?
void f (void (*g) (int)) {
g(2);
}
struct A {
int x;
void foo (int c) { x += c; }
};
f(&A::foo); // Oh oh! Where will I find `x` in the call `g(2)`?
如果您只想指向B
的方法,则需要更改回调类型:
void A::SetCallback(void (B::*callback)(int)) { }
但是你需要一个B
的实例来调用你的回调,例如:
B b;
(b.*callback)(2);
答案 3 :(得分:1)
我使用以下代码。它不漂亮,但你要求C ++ 03:
#include <iostream>
#include <vector>
#include <functional>
class AbstractCallback {
public:
virtual void call(int arg) = 0;
};
template <class T>
class Callback : public AbstractCallback {
public:
typedef std::mem_fun1_t<void, T, int> CallbackFunc;
private:
CallbackFunc func;
T* object;
public:
Callback(T* _object, const CallbackFunc& _func)
: object(_object), func(_func) {
}
void call(int arg) {
func(object, arg);
}
};
struct A {
void foo(int a) {
std::cout << "foo " << a << std::endl;
}
};
struct B {
void bar(int a) {
std::cout << "bar " << a << std::endl;
}
};
int main() {
A a;
B b;
AbstractCallback* cbs[2] = {
new Callback<A>(&a, std::mem_fun(&A::foo)),
new Callback<B>(&b, std::mem_fun(&B::bar)),
};
cbs[0]->call(10);
cbs[1]->call(22);
delete cbs[0];
delete cbs[1];
return 0;
}
正如您所见,指针成员函数(类型A::*
和B::*
)被包装到std::mem_fun
和一个为每种类型生成的Callback
类中(在这种情况下为A
和B
)。
这允许在矢量,数组或抽象回调列表中保留任何类型的方法。