Instantiating C++ lambda by its type

前端 未结 4 1472
野性不改
野性不改 2021-01-01 13:08

I want a way to make functor from function. Now I trying to wrap function call by lambda function and instantiate it later. But compiler says than lambda constructor is dele

4条回答
  •  醉话见心
    2021-01-01 13:36

    Lambdas do not have default constructors. Ever. The only constructors they sometimes give access to is (depending on what they capture) the copy and/or move constructors.

    If you create a functor with no public default constructor, you'll get the same error.

    In C++17 you can solve this with constexpr lambda and operator+ to decay-to-function pointer. A type that carries a function pointer and invokes it is easy with auto template parameters.

    In C++11 you gotta get a bit hacky.

    template
    struct stateless_lambda_t {
      static std::aligned_storage_t< sizeof(F), alignof(F) >& data() {
        static std::aligned_storage_t< sizeof(F), alignof(F) > retval;
        return retval;
      };
      template, stateless_lambda_t >{}, int> =0
      >
      stateless_lambda_t( Fin&& f ) {
        new ((void*)&data()) F( std::forward(f) );
      }
      stateless_lambda_t(stateless_lambda_t const&)=default;
      template
      decltype(auto) operator()(Args&&...args)const {
        return (*static_cast( (void*)&data() ))(std::forward(args)...);
      }
      stateless_lambda_t() = default;
    };
    template
    stateless_lambda_t> make_stateless( F&& fin ) {
      return {std::forward(fin)};
    }
    

    Now we can:

    auto t = make_stateless([]{ func(); });
    

    and your code works.

    A static_assert or SFINAE that the F is actually an empty type might be a good idea. You know, for quality.

    The use of C++14 features can be replaced with manual decltype and spewing typename and ::type keywords. This answer was originally written for a C++14 question that was closed as a duplicate of this one.

    live example.

提交回复
热议问题