且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

神奇的模板用于包装该拿的void *参数Ç回调?

更新时间:2023-11-30 21:36:46

我发现了一个更好的回答这个问题比这里给我其他的答案! (其实这是谷歌内部一位工程师谁建议的话)。

I have discovered a better answer to this question than the other answers given to me here! (Actually it was another engineer inside Google who suggested it).

您必须重复函数名的两倍,但可以与宏来解决。

You have to repeat the function name twice, but that can be solved with a macro.

其基本模式是:

// Func1, Func2, Func3: Template classes representing a function and its
// signature.
//
// Since the function is a template parameter, calling the function can be
// inlined at compile-time and does not require a function pointer at runtime.
// These functions are not bound to a handler data so have no data or cleanup
// handler.
template <class R, class P1, R F(P1)>
struct Func1 {
  typedef R Return;
  static R Call(P1 p1) { return F(p1); }
};

// ...

// FuncSig1, FuncSig2, FuncSig3: template classes reflecting a function
// *signature*, but without a specific function attached.
//
// These classes contain member functions that can be invoked with a
// specific function to return a Func/BoundFunc class.
template <class R, class P1>
struct FuncSig1 {
  template <R F(P1)>
  Func1<R, P1, F> GetFunc() { return Func1<R, P1, F>(); }
};

// ...

// Overloaded template function that can construct the appropriate FuncSig*
// class given a function pointer by deducing the template parameters.
template <class R, class P1>
inline FuncSig1<R, P1> MatchFunc(R (*f)(P1)) {
  (void)f;  // Only used for template parameter deduction.
  return FuncSig1<R, P1>();
}

// ...

// Function that casts the first parameter to the given type.
template <class R, class P1, R F(P1)>
R CastArgument(void *c) {
  return F(static_cast<P1>(c));
}

template <class F>
struct WrappedFunc;

template <class R, class P1, R F(P1)>
struct WrappedFunc<Func1<R, P1, F> > {
  typedef Func1<R, void*, CastArgument<R, P1, F> > Func;
};

template <class T>
generic_func_t *GetWrappedFuncPtr(T func) {
  typedef typename WrappedFunc<T>::Func Func;
  return Func().Call;
}

// User code:

#include <iostream>

typedef void (generic_func_t)(void*);

void StronglyTypedFunc(int *x) {
  std::cout << "value: " << *x << "\n";
}

int main() {
  generic_func_t *f = GetWrappedFuncPtr(
      MatchFunc(StronglyTypedFunc).GetFunc<StronglyTypedFunc>());
  int x = 5;
  f(&x);
}

这是不是太短或简单,但它是正确的,原则性强,符合标准的!

This is not short or simple, but it is correct, principled, and standard-compliant!

这让我我想要的:


  • 的用户获取写StronglyTypedFunc()取一个指向一个具体的事情。

  • 这个功能可以为void *参数调用。

  • 有没有虚函数的开销或间接。