此代码在这里工作正常。它喊
真的!
错!
#include <iostream>
#include <boost/bind.hpp>
#include <boost/function.hpp>
//typedef bool(callback) (int, int);
typedef boost::function<bool(int, int)> callback;
void print_result(callback handle, int first, int second)
{
if(handle == nullptr)
return;
if(handle(first, second))
std::cout << "True!\n";
else
std::cout << "False!\n";
}
class Callback
{
public:
Callback(bool type) : m_type(type)
{}
bool operator() (int foo, int bar)
{
return m_type ? foo > bar : foo < bar;
}
private:
bool m_type;
};
int main()
{
print_result(Callback(false), 2, 3);
print_result(Callback(true), 2, 3);
return 0;
}
但是不幸的是,我必须使其与良好的旧函数指针一起使用。我从未在实践中使用过它们,我对它们也不了解。显而易见,签名“ bool operator()(int foo,int bar)”不容易转换为“ bool(callback)(int,int)”。
我从gcc收到的错误代码:
prog.cc: In function 'int main()':
prog.cc:34:18: error: cannot convert 'Callback' to 'bool (*)(int, int)'
print_result(Callback(false), 2, 3);
^~~~~~~~~~~~~~~
prog.cc:8:28: note: initializing argument 1 of 'void print_result(bool (*)(int, int), int, int)'
void print_result(callback handle, int first, int second)
~~~~~~~~~^~~~~~
prog.cc:35:18: error: cannot convert 'Callback' to 'bool (*)(int, int)'
print_result(Callback(true), 2, 3);
^~~~~~~~~~~~~~
prog.cc:8:28: note: initializing argument 1 of 'void print_result(bool (*)(int, int), int, int)'
void print_result(callback handle, int first, int second)
反正有解决办法吗?顺便说一句,我不介意使用其他解决方案。例如,可以使用“ boost :: bind”来传递bool参数,但是绑定也不起作用。出于同样的原因。
想法,有人吗?预先感谢!
注意:我无法更改“ print_result”函数的签名。诸如“使用X代替函数指针”之类的解决方案不在桌面上。
答案 0 :(得分:2)
回调允许额外参数的传统方式是让用户提供额外的void*
。
using callback = bool (int, int, void* userData);
bool run_callback(int a, int b, void* userData) {
CallBack* c = reinterpret_cast<void*>(userData);
return (*c)(a, b);
}
CallBack t(true);
Register(&run_callback, &t); // Would call later run_callback(2, 3, &t);
如果您无法更改签名,则可以使用global来传递该额外的参数,因此有一些限制。
Callback* global = nullptr;
bool RunCallBack(int foo, int bar)
{
assert(global != nullptr);
return (*global)(foo, bar);
}
然后
Callback f(false);
Callback t(true);
global = &f;
print_result(&RunCallBack, 2, 3);
global = &t;
print_result(&RunCallBack, 2, 3);
答案 1 :(得分:0)
如果您不介意传递其他参数,则可以执行以下操作:
#include <iostream>
#include <functional>
template<typename T>
using callback = bool(T::*) (int, int);
template<typename T>
void print_result(T t, callback<T> handle, int first, int second) {
if(handle == nullptr)
return;
if((t.*handle)(first, second))
std::cout << "True!\n";
else
std::cout << "False!\n";
}
class Callback {
public:
Callback(bool type) : m_type(type) {}
bool operator() (int foo, int bar) {
return m_type ? foo > bar : foo < bar;
}
private:
bool m_type;
};
int main() {
print_result(Callback(false), &Callback::operator(), 2, 3);
print_result(Callback(true), &Callback::operator(), 2, 3);
}
答案 2 :(得分:0)
不更改print_result
,您必须根据自变量向Callback
发送不同的函数。
将单个bool参数移动为模板参数非常简单,但是如果存在无法constexpr构造的状态,则会变得笨拙。
template<bool type>
bool Callback (int foo, int bar);
template<>
bool Callback<true> (int foo, int bar)
{
return foo > bar;
}
template<>
bool Callback<false> (int foo, int bar)
{
return foo < bar;
}
int main()
{
print_result(Callback<false>, 2, 3);
print_result(Callback<true>, 2, 3);
return 0;
}
如果需要根据运行时值进行选择
callback select_callback(bool type)
{
return type ? Callback<true> : Callback<false>;
}
答案 3 :(得分:0)