简体   繁体   English

为C++中不同参数的回调创建多个function指针

[英]Create multiple function pointers for callbacks with different parameters in C++

I have a third party class Calculation with a function setCallback :我有一个第三方 class 使用 function setCallback Calculation

typedef void (*callback_function)(void);

class Calculation
{
public:
    void setCallback(callback_function pFunc);
};

and my function I want to use as callback和我的 function 我想用作回调

void callback(int id);

I want to create, say, four (number known at compile time) objects of Calculation and set the callback for each object.例如,我想创建四个(编译时已知的数量) Calculation对象并为每个 object 设置回调。 I could do something like我可以做类似的事情

void callback0() { callback(0); }
void callback1() { callback(1); }
void callback2() { callback(2); }
void callback3() { callback(3); }

int main() {
  std::vector<Calculation> vec;

  for (int i = 0; i < 4; i++) {
    Calculation c = Calculation();
    vec.push_back(c);
  }

  vec[0].setCallback(callback0);
  vec[1].setCallback(callback1);
  vec[2].setCallback(callback2);
  vec[3].setCallback(callback3);

  return 0;
}

Question: How can I achieve this without duplicating and repeating code?问题:如何在不重复和重复代码的情况下实现这一目标?

I was thinking of lamdas, like我在想lamdas,比如

  for (int i = 0; i < 4; i++) {
    Calculation c = Calculation();
    c.setCallback([i]() -> void {callback(i);});
    vec.push_back(c);
  }

but a lambda can only be converted to a function pointer if it does not capture .但是如果 lambda 没有捕获,则只能转换为 function 指针

Template function might help:模板 function 可能会有所帮助:

template <int N>
void callbackN() { callback(N); }

and then接着

vec[0].setCallback(callback<0>);
vec[1].setCallback(callback<1>);
vec[2].setCallback(callback<2>);
vec[3].setCallback(callback<3>);

Since the number of Calculation instances is known at compile-time, you set up something like this to automate things, but not sure if it's worth the effort:由于 Calculation 实例的数量在编译时是已知的,因此您设置了这样的东西来自动化事情,但不确定是否值得付出努力:

template <size_t Size, typename Idx = std::make_index_sequence<Size>>
class CalcInterface {
    std::array<callback_function, Size> m_callbacks { makeCallbacks(Idx{}) };
    std::array<Calculation, Size> m_calcs;

protected:
    template <size_t N> 
    static inline callback_function makeCallback() {
        return []{ return callback(N); };
    }
    template <size_t... Seq>
    static inline auto makeCallbacks(std::index_sequence<Seq...>) {
        std::array<callback_function, Size> arr;
        ((arr[Seq] = makeCallback<Seq>()), ...);
        return arr;
    }

    static void callback(int id) { 
        std::cout << "Callback #" << id << " was called\n";
    }

public:
    CalcInterface() {
        for (size_t i=0; i<Size; ++i) {
            m_calcs[i].setCallback(m_callbacks[i]);
        }
    }

    void runAll() const {
        for (auto& calc: m_calcs) calc.run();
    }
};

Example here: https://godbolt.org/z/sWTzn59ce此处示例: https://godbolt.org/z/sWTzn59ce

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM