当前位置: 首页 > 知识库问答 >
问题:

我可以将Functor类(重载operator())传递给需要函数指针的函数吗?以及如何[复制]

呼延宪
2023-03-14

这里的代码工作得很好。这可能
是真的
错误
应该如此

#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;
}

但不幸的是,我必须让它与旧的函数指针一起工作。我从不在实践中使用它们,我对它们也知之甚少。很明显,签名“布尔运算符()(整型 foo,整型柱线)”不容易转换为“bool(回调)(整型,整型)”。

我从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) 

有办法解决吗?顺便说一下,我不介意有一个不同的解决方案。例如,bool参数可以通过使用::bind来传递,但是绑定也不起作用。出于同样的原因。
想法,有人吗?提前感谢!

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

共有3个答案

祖翰音
2023-03-14

不更改< code>print_result,您必须根据您的参数向< code>Callback发送不同的函数

将单个 bool 参数移动为模板参数相当简单,但如果存在无法构造的状态,则会变得笨拙。

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>;
}
姜建德
2023-03-14

如果您不介意传递其他参数,可以执行以下操作:

#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);
}
方夜洛
2023-03-14

允许额外参数的回调的传统方法是具有用户提供的额外 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++ 指针 C++ 允许您传递指针给函数,只需要简单地声明函数参数为指针类型即可。 下面的实例中,我们传递一个无符号的 long 型指针给函数,并在函数内改变这个值: #include <iostream> #include <ctime> using namespace std; void getSeconds(unsigned long *par); int main () {

  • 问题内容: 为了不重复我的自我,我想创建一个函数来处理一些命令。 一旦我尝试运行它,我得到以下错误: 我研究了的实现,并且看起来函数签名正是我提供的。 在内部a 应该与可变参数相同,但对于编译器来说似乎不一样。 有没有办法将可变参数传递给? 问题答案: 您用另一个扩展 从语言规范的传递参数…参数 如果最终参数可分配给切片类型,则在参数后跟时可以将其作为参数的值原样传递。在这种情况下,不会创建新的切

  • 我编写了一个代码来传递函数指针列表(按其名称)作为参数。但我有错误。你能解释为什么我在做地图时有错误吗? 错误: 34:18:错误:无法将'void(Bar::)(int, int)'转换为'std::map, void(*)(int, int) 35:18:错误:无法将“无效(foo::)(整数,整数)”转换为“标准::映射,无效(*)(整数,整型) 41:70:错误:没有用于调用“std::v

  • 在第4.9小节,我们已经知道,切片实际是一个指向潜在数组的指针。我们常常需要把切片作为一个参数传递给函数是因为:实际就是传递一个指向变量的指针,在函数内可以改变这个变量,而不是传递数据的拷贝。 因此应该这样做: func findBiggest( listOfNumbers []int ) int {} 而不是: func findBiggest( listOfNumbers *[]i

  • 我正在尝试编写一个类模板,在内部它使用一个函数(BFGS优化的实现,由环境提供),接口如下: 其中< code>fn和< code>gr是类型的函数指针 和 分别是。我的< code>C 类模板如下所示: 这样,它可以由任何具有两个指定成员函数的类进行实例化,例如: 这可能吗?或者也许有更好的方法来做到这一点 - 将两个成员函数分别作为函数指针传递?(如果目标函数和相应的梯度很简单,那么编写两个函

  • 我一直只使用Java6,现在正在赶上学习Java8的新内容。我在这里读了这篇文章:http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764?pgno=2 上面写着: Java API在Java中定义了几个通用功能接口。util。功能包。其中一个接口BiFunction描述了参数类型为T和U以及返回类型为R的函数。您可以将字符