c++ - 我可以将 Functor 类(重载运算符())传递给需要函数指针的函数吗?如何

标签 c++ boost

这里的代码工作得很好。它算出
确实!
错误!
理应如此

#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参数,但绑定(bind)也不起作用。为了同样的原因。
有什么想法吗?提前致谢!

注意:我无法更改“print_result”函数的签名。像“使用 X 而不是函数指针”这样的解决方案是不可能的。

最佳答案

回调允许额外参数的传统方法是让用户提供额外的void*

using callback = bool (int, int, void* userData);

bool run_callback(int a, int b, void* userData) {
    CallBack* c = reinterpret_cast<CallBack*>(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);

关于c++ - 我可以将 Functor 类(重载运算符())传递给需要函数指针的函数吗?如何,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53222341/

相关文章:

c++ - 静态断言捕获的 lambda

c++ - 如何在 Visual Studio 中静态链接 FreeType2?

c++ - 将多映射迭代器转换为随机访问迭代器

C++11 如何在编译时识别原子类型(通过 mtl 或定义)?

c++ - 来自 Boost 的 JSON 解析器的警告 C4512 的解决方法

c++ - 用C++高效地读取部分文本

c++ - 串口计数器

c++ - pthread_cond_timedwait() 用于取消冗长任务

c++ - 使用 boost::spirit 将元素解析为 vector ,使用分号或换行符作为分隔符

c++ - 当入口和导出指向不同的节点时,如何使用 boost::graph 来(大约)解决旅行商问题?