如何在函数声明中声明 C++ mem_fn(member_function)?
How declare a C++ mem_fn(member_function) in function declaration?
我理解在 class 之外传递成员函数地址的基本问题。我觉得 mem_fn() 可能是解决方案,但我在具体细节上遇到了麻烦。
我在 class p 中有一个成员函数,当前声明为
typedef void (*valNamedFlagsCallback)(const int, const bool);
bool valNamedFlags(const OptBlk *operand, const char *description_of_value_or_NULL, const int subscripts[], const char *names[], valNamedFlagsCallback callBack);
在 class e 中,我正在尝试使用
调用 valNamedFlags
pInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, std::mem_fn(&e::setStatement));
(我开始时没有 mem_fn() 但当然有 classic "pointers to member functions" 问题。我已经尝试了 &e::setStatement 和普通的 &setStatement .)
FWIW,setStatement 的原型为
void setStatement(const int ifcid, const bool isAffirmative);
如果我删除 mem_fn() 并将 setStatement 声明为静态,则一切正常。我只是指出这一点,以此表示我已经消除了所有其他可能的问题;我唯一的问题是 "pointers to member functions" 问题。不幸的是,setStatement() 需要是一个成员函数,而不是一个静态函数。
我在 MS VS 2010 中遇到的具体错误是
bool p::valNamedFlags(const OptBlk *,const char *,const int [],const char *[],p::valNamedFlagsCallback)' : cannot convert parameter 5 from 'std::tr1::_Mem_fn3<_Rx,_Pmf,_Arg0,_Arg1,_Arg2>' to 'p::valNamedFlagsCallback'
我想让回调声明独立于 class e;也就是说,我不想去
typedef void (*e::valNamedFlagsCallback)(const int, const bool);
因为我想让 p 比那更普遍。
mem_fn() 是正确的解决方案还是我离题太远了?如果是这样,我应该如何在 valNamedFlags() 原型中声明回调?
或者我应该采用不同的方法吗?
你需要bind
一个实例在它上面通过成员函数指针调用。 (即 std::bind(&e::setStatement, eInstance, _1, _2)
,假设 eInstance
是指向 class e
的对象的指针。
using namespace std::placeholders; // for _1, _2, _3...
pInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, std::bind(&e::setStatement, eInstance, _1, _2));
注意 std::bind
的 return 值(未指定)与自由函数指针类型 valNamedFlagsCallback
不匹配,解决方案之一是使用 std::function
.
typedef std::function<void(const int, const bool)> valNamedFlagsCallback;
实际上,按照某些人的建议,您在执行类似绑定的操作时会遇到问题,因为您的回调被定义为简单的函数指针,而不是可调用的。
如果你负担得起,你可以改变你的
typedef void (*valNamedFlagsCallback)(const int, const bool);
类似于
typedef std::function<void(int, bool)> valNamedFlagsCallback
(还要注意值参数上的 const
不影响函数的签名),那么你可以使用 std::bind()
,
using namespace std::placeholders;
pInstance->valNamedFlags(operand,
"Statement types",
statementsSubscripts,
statementsNames,
std::bind(&E::setStatement, e, _1, _2));
或者你可以使用 lambdas:
pInstance->valNamedFlags(operand,
"Statement types",
statementsSubscripts,
statementsNames,
[&](int i, bool b) { e->setStatement(i, b); });
如果您必须将其保留为一个简单的函数,那么您将必须发送一个引用正确对象的函数作为 global/static 变量。
知道了!!!谢谢大家!!!
原型:
bool valNamedFlags(const OptBlk *operand, const char *description_of_value_or_NULL, const int subscripts[], const char *names[], std::function<void(int,bool)> callBack);
通话:
valNamedFlags(..., std::bind(&e::setStatement, this, _1, _2));
实际运行并使用正确的参数调用 setStatement。
我理解在 class 之外传递成员函数地址的基本问题。我觉得 mem_fn() 可能是解决方案,但我在具体细节上遇到了麻烦。
我在 class p 中有一个成员函数,当前声明为
typedef void (*valNamedFlagsCallback)(const int, const bool);
bool valNamedFlags(const OptBlk *operand, const char *description_of_value_or_NULL, const int subscripts[], const char *names[], valNamedFlagsCallback callBack);
在 class e 中,我正在尝试使用
调用 valNamedFlagspInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, std::mem_fn(&e::setStatement));
(我开始时没有 mem_fn() 但当然有 classic "pointers to member functions" 问题。我已经尝试了 &e::setStatement 和普通的 &setStatement .)
FWIW,setStatement 的原型为
void setStatement(const int ifcid, const bool isAffirmative);
如果我删除 mem_fn() 并将 setStatement 声明为静态,则一切正常。我只是指出这一点,以此表示我已经消除了所有其他可能的问题;我唯一的问题是 "pointers to member functions" 问题。不幸的是,setStatement() 需要是一个成员函数,而不是一个静态函数。
我在 MS VS 2010 中遇到的具体错误是
bool p::valNamedFlags(const OptBlk *,const char *,const int [],const char *[],p::valNamedFlagsCallback)' : cannot convert parameter 5 from 'std::tr1::_Mem_fn3<_Rx,_Pmf,_Arg0,_Arg1,_Arg2>' to 'p::valNamedFlagsCallback'
我想让回调声明独立于 class e;也就是说,我不想去
typedef void (*e::valNamedFlagsCallback)(const int, const bool);
因为我想让 p 比那更普遍。
mem_fn() 是正确的解决方案还是我离题太远了?如果是这样,我应该如何在 valNamedFlags() 原型中声明回调?
或者我应该采用不同的方法吗?
你需要bind
一个实例在它上面通过成员函数指针调用。 (即 std::bind(&e::setStatement, eInstance, _1, _2)
,假设 eInstance
是指向 class e
的对象的指针。
using namespace std::placeholders; // for _1, _2, _3...
pInstance->valNamedFlags(operand, "Statement types", statementsSubscripts, statementsNames, std::bind(&e::setStatement, eInstance, _1, _2));
注意 std::bind
的 return 值(未指定)与自由函数指针类型 valNamedFlagsCallback
不匹配,解决方案之一是使用 std::function
.
typedef std::function<void(const int, const bool)> valNamedFlagsCallback;
实际上,按照某些人的建议,您在执行类似绑定的操作时会遇到问题,因为您的回调被定义为简单的函数指针,而不是可调用的。
如果你负担得起,你可以改变你的
typedef void (*valNamedFlagsCallback)(const int, const bool);
类似于
typedef std::function<void(int, bool)> valNamedFlagsCallback
(还要注意值参数上的 const
不影响函数的签名),那么你可以使用 std::bind()
,
using namespace std::placeholders;
pInstance->valNamedFlags(operand,
"Statement types",
statementsSubscripts,
statementsNames,
std::bind(&E::setStatement, e, _1, _2));
或者你可以使用 lambdas:
pInstance->valNamedFlags(operand,
"Statement types",
statementsSubscripts,
statementsNames,
[&](int i, bool b) { e->setStatement(i, b); });
如果您必须将其保留为一个简单的函数,那么您将必须发送一个引用正确对象的函数作为 global/static 变量。
知道了!!!谢谢大家!!!
原型:
bool valNamedFlags(const OptBlk *operand, const char *description_of_value_or_NULL, const int subscripts[], const char *names[], std::function<void(int,bool)> callBack);
通话:
valNamedFlags(..., std::bind(&e::setStatement, this, _1, _2));
实际运行并使用正确的参数调用 setStatement。