c++ function

2022-09-18  本文已影响0人  help_youself

 code copied from clang/lib/Parse/ParseDecl.cpp#L4426

#include <type_traits>
#include <utility>
#include <cstdint>
#include <iostream>
#include <functional>
template <typename T>
struct remove_cvref // NOLINT(readability-identifier-naming)
{
  using type = std::remove_cv_t<std::remove_reference_t<T>>;
};

template <typename T>
using remove_cvref_t // NOLINT(readability-identifier-naming)
    = typename remove_cvref<T>::type;

template<typename Fn> class function_ref;

template<typename Ret, typename ...Params>
class function_ref<Ret(Params...)> {
  Ret (*callback)(intptr_t callable, Params ...params) = nullptr;
  intptr_t callable;

  template<typename Callable>
  static Ret callback_fn(intptr_t callable, Params ...params) {
    return (*reinterpret_cast<Callable*>(callable))(
        std::forward<Params>(params)...);
  }

public:
  function_ref() = default;
  function_ref(std::nullptr_t) {}

  template <typename Callable>
  function_ref(
      Callable &&callable,
      // This is not the copy-constructor.
      std::enable_if_t<!std::is_same<remove_cvref_t<Callable>,
                                     function_ref>::value> * = nullptr,
      // Functor must be callable and return a suitable type.
      std::enable_if_t<std::is_void<Ret>::value ||
                       std::is_convertible<decltype(std::declval<Callable>()(
                                               std::declval<Params>()...)),
                                           Ret>::value> * = nullptr)
      : callback(callback_fn<typename std::remove_reference<Callable>::type>),
        callable(reinterpret_cast<intptr_t>(&callable)) {}

  Ret operator()(Params ...params) const {
    return callback(callable, std::forward<Params>(params)...);
  }

  explicit operator bool() const { return callback; }
};
struct Data{
    int a;
    int b;
};
void test_callback(function_ref<void(Data&)> callback){
    Data data={1,3};
    callback(data);
}
void test_std_fun(std::function<void(Data&)> callback){
    Data data={12,3};
    callback(data);
}
int main(){
    int a=123;
    auto callback=[&](Data &data){
        std::cout<<a<<" "<<data.a<<std::endl;
    };
    test_callback(callback);
    test_std_fun(callback);
    std::cout<<"hello world"<<std::endl;
}

Reference:
[1]c++ std::function

上一篇下一篇

猜你喜欢

热点阅读