Is it possible to pass generic lambda as non-template argumentHow does generic lambda work in C++14?Template class generate errors in C++C++11 g++ strangeness (using defaulted template, lambda & remove_if)Compiling with gcc fails if using lambda function for QObject::connect()Distingushing between user and non-user types & templates specializationEnable method based on boolean template parameterPassing different lambdas to function template in c++Cross-platform “auto” keyword usage in lambdas: integral_constant as function argumentPassing variadic template to pthread_createConstructing std::function argument from lambdaInfering template type from function argument

Host telling me to cancel my booking in exchange for a discount?

Considerations when providing money to only one child out of two

Is it OK to accept a job opportunity while planning on not taking it?

Trivial non-dark twist in dark fantasy

Hats Question: Confusion Over Its Formulation

How can I remove studs and screws from the inside of drywall when installing a pocket door without needing to do paint and patch work on both sides?

Can the caster of Time Stop still use their bonus action or reaction?

Piece of fabric in planter, how to use it?

Why do we need an estimator to be consistent?

On a Gameboy, what happens when attempting to read/write external RAM while RAM is disabled?

Acoustic guitar chords' positions vs those of a Bass guitar

What would be the effects of (relatively) widespread precognition on the stock market?

Strange LED behavior

What is the AI assistant for the Iron Man Rescue armor?

Importance of moon phases for Apollo missions

"It is what it is"

What are "the high ends of castles" called?

How to handle not being able to attend as often as I'd like

Why does the salt in the oceans not sink to the bottom?

Finding Greatest Common Divisor using LuaLatex

My current job follows "worst practices". How can I talk about my experience in an interview without giving off red flags?

Can a creature sustain itself by eating its own severed body parts?

What does the following chess proverb mean: "Chess is a sea where a gnat may drink from and an elephant may bathe in."

Why was Quirrell said to be in the Black Forest if Voldemort was actually in Albania?



Is it possible to pass generic lambda as non-template argument


How does generic lambda work in C++14?Template class generate errors in C++C++11 g++ strangeness (using defaulted template, lambda & remove_if)Compiling with gcc fails if using lambda function for QObject::connect()Distingushing between user and non-user types & templates specializationEnable method based on boolean template parameterPassing different lambdas to function template in c++Cross-platform “auto” keyword usage in lambdas: integral_constant as function argumentPassing variadic template to pthread_createConstructing std::function argument from lambdaInfering template type from function argument






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








8















I have a toy example that I'd like to modify architecturally to remove type dependency of Processor on EmitterT:



#include <iostream>
#include <utility>

using namespace std;

struct Emitter
void e(int) cout << "emitting intn";
void e(double) cout << "emitting doublen";
void e(char*) cout << "emitting char*n";
void e(const char*) cout << "emitting const char*n";
;

template <typename EmitterT>
struct Processor

Processor(EmitterT e) : e_e

template <typename T>
void process(T&& value)
cout << "some processing... ";
e_(std::forward<T>(value));


EmitterT e_;

;

template<typename Emitter_>
Processor<Emitter_> makeProcessor(Emitter_ e) return Processor<Emitter_>(e);

int main()
Emitter em;
auto p = makeProcessor([&em](auto v)em.e(v););


p.process(1);
p.process("lol");
return 0;



Motivation



I'd like to decouple part responsible for utilizing results of processing from the processing itself. The Emitter class structure is given to me, so I have to support overloaded functions.



I'd like to pass a lambda function to a processor that will use it. Kind of like a callback mechanism, however it must be a generic lambda, to support overloads.



What I've tried:



The example I wrote works, but it depends on Emitter type as a template parameter. I don't like Processor type to change based on Emitter. It's also contagious, I have a real Processor hierarchy and Emitter spread like const or worse.



After reading https://stackoverflow.com/a/17233649/1133179 I've tried playing with below struct as a member:



struct EmitterC 
template<typename T>
void operator()(T value)
;


But I cannot figure out a way to defer implementation of Emitter after Processor when using it as a normal parameter. It worked out with a forward declaration and a reference EmitterC& but it supports one only Emitter definition. The only way I could come up with was to drop lambda, and make virtual overloads in EmitterC for every type I expect in Emitter and use it as a base class.



So, Is there a way to pass the (generic) lambda as a parameter, so that Processor type doesn't depend on Emitter?



I am restricted to c++14, but I am interested in more modern standards as well if the have better support.










share|improve this question

















  • 1





    In your code, there is no need to store emitter as a member, so you can simply accept it is a parameter as well.

    – SergeyA
    8 hours ago











  • You can make the constructor a templated function instead, and type-erase it into a std::function class member.

    – Sam Varshavchik
    8 hours ago






  • 3





    @SamVarshavchik: what would the signature of that std::function be?

    – Vittorio Romeo
    8 hours ago











  • The types of parameters the lambda takes, and its return value.

    – Sam Varshavchik
    7 hours ago






  • 1





    Type-erase the parameter to the lambda itself. At some point, somewhere, the type must be known, or determined someway. Nothing more can really be said about this, is is too vague, at this point.

    – Sam Varshavchik
    7 hours ago

















8















I have a toy example that I'd like to modify architecturally to remove type dependency of Processor on EmitterT:



#include <iostream>
#include <utility>

using namespace std;

struct Emitter
void e(int) cout << "emitting intn";
void e(double) cout << "emitting doublen";
void e(char*) cout << "emitting char*n";
void e(const char*) cout << "emitting const char*n";
;

template <typename EmitterT>
struct Processor

Processor(EmitterT e) : e_e

template <typename T>
void process(T&& value)
cout << "some processing... ";
e_(std::forward<T>(value));


EmitterT e_;

;

template<typename Emitter_>
Processor<Emitter_> makeProcessor(Emitter_ e) return Processor<Emitter_>(e);

int main()
Emitter em;
auto p = makeProcessor([&em](auto v)em.e(v););


p.process(1);
p.process("lol");
return 0;



Motivation



I'd like to decouple part responsible for utilizing results of processing from the processing itself. The Emitter class structure is given to me, so I have to support overloaded functions.



I'd like to pass a lambda function to a processor that will use it. Kind of like a callback mechanism, however it must be a generic lambda, to support overloads.



What I've tried:



The example I wrote works, but it depends on Emitter type as a template parameter. I don't like Processor type to change based on Emitter. It's also contagious, I have a real Processor hierarchy and Emitter spread like const or worse.



After reading https://stackoverflow.com/a/17233649/1133179 I've tried playing with below struct as a member:



struct EmitterC 
template<typename T>
void operator()(T value)
;


But I cannot figure out a way to defer implementation of Emitter after Processor when using it as a normal parameter. It worked out with a forward declaration and a reference EmitterC& but it supports one only Emitter definition. The only way I could come up with was to drop lambda, and make virtual overloads in EmitterC for every type I expect in Emitter and use it as a base class.



So, Is there a way to pass the (generic) lambda as a parameter, so that Processor type doesn't depend on Emitter?



I am restricted to c++14, but I am interested in more modern standards as well if the have better support.










share|improve this question

















  • 1





    In your code, there is no need to store emitter as a member, so you can simply accept it is a parameter as well.

    – SergeyA
    8 hours ago











  • You can make the constructor a templated function instead, and type-erase it into a std::function class member.

    – Sam Varshavchik
    8 hours ago






  • 3





    @SamVarshavchik: what would the signature of that std::function be?

    – Vittorio Romeo
    8 hours ago











  • The types of parameters the lambda takes, and its return value.

    – Sam Varshavchik
    7 hours ago






  • 1





    Type-erase the parameter to the lambda itself. At some point, somewhere, the type must be known, or determined someway. Nothing more can really be said about this, is is too vague, at this point.

    – Sam Varshavchik
    7 hours ago













8












8








8


2






I have a toy example that I'd like to modify architecturally to remove type dependency of Processor on EmitterT:



#include <iostream>
#include <utility>

using namespace std;

struct Emitter
void e(int) cout << "emitting intn";
void e(double) cout << "emitting doublen";
void e(char*) cout << "emitting char*n";
void e(const char*) cout << "emitting const char*n";
;

template <typename EmitterT>
struct Processor

Processor(EmitterT e) : e_e

template <typename T>
void process(T&& value)
cout << "some processing... ";
e_(std::forward<T>(value));


EmitterT e_;

;

template<typename Emitter_>
Processor<Emitter_> makeProcessor(Emitter_ e) return Processor<Emitter_>(e);

int main()
Emitter em;
auto p = makeProcessor([&em](auto v)em.e(v););


p.process(1);
p.process("lol");
return 0;



Motivation



I'd like to decouple part responsible for utilizing results of processing from the processing itself. The Emitter class structure is given to me, so I have to support overloaded functions.



I'd like to pass a lambda function to a processor that will use it. Kind of like a callback mechanism, however it must be a generic lambda, to support overloads.



What I've tried:



The example I wrote works, but it depends on Emitter type as a template parameter. I don't like Processor type to change based on Emitter. It's also contagious, I have a real Processor hierarchy and Emitter spread like const or worse.



After reading https://stackoverflow.com/a/17233649/1133179 I've tried playing with below struct as a member:



struct EmitterC 
template<typename T>
void operator()(T value)
;


But I cannot figure out a way to defer implementation of Emitter after Processor when using it as a normal parameter. It worked out with a forward declaration and a reference EmitterC& but it supports one only Emitter definition. The only way I could come up with was to drop lambda, and make virtual overloads in EmitterC for every type I expect in Emitter and use it as a base class.



So, Is there a way to pass the (generic) lambda as a parameter, so that Processor type doesn't depend on Emitter?



I am restricted to c++14, but I am interested in more modern standards as well if the have better support.










share|improve this question














I have a toy example that I'd like to modify architecturally to remove type dependency of Processor on EmitterT:



#include <iostream>
#include <utility>

using namespace std;

struct Emitter
void e(int) cout << "emitting intn";
void e(double) cout << "emitting doublen";
void e(char*) cout << "emitting char*n";
void e(const char*) cout << "emitting const char*n";
;

template <typename EmitterT>
struct Processor

Processor(EmitterT e) : e_e

template <typename T>
void process(T&& value)
cout << "some processing... ";
e_(std::forward<T>(value));


EmitterT e_;

;

template<typename Emitter_>
Processor<Emitter_> makeProcessor(Emitter_ e) return Processor<Emitter_>(e);

int main()
Emitter em;
auto p = makeProcessor([&em](auto v)em.e(v););


p.process(1);
p.process("lol");
return 0;



Motivation



I'd like to decouple part responsible for utilizing results of processing from the processing itself. The Emitter class structure is given to me, so I have to support overloaded functions.



I'd like to pass a lambda function to a processor that will use it. Kind of like a callback mechanism, however it must be a generic lambda, to support overloads.



What I've tried:



The example I wrote works, but it depends on Emitter type as a template parameter. I don't like Processor type to change based on Emitter. It's also contagious, I have a real Processor hierarchy and Emitter spread like const or worse.



After reading https://stackoverflow.com/a/17233649/1133179 I've tried playing with below struct as a member:



struct EmitterC 
template<typename T>
void operator()(T value)
;


But I cannot figure out a way to defer implementation of Emitter after Processor when using it as a normal parameter. It worked out with a forward declaration and a reference EmitterC& but it supports one only Emitter definition. The only way I could come up with was to drop lambda, and make virtual overloads in EmitterC for every type I expect in Emitter and use it as a base class.



So, Is there a way to pass the (generic) lambda as a parameter, so that Processor type doesn't depend on Emitter?



I am restricted to c++14, but I am interested in more modern standards as well if the have better support.







c++ lambda c++14






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 8 hours ago









luk32luk32

13k26 silver badges48 bronze badges




13k26 silver badges48 bronze badges







  • 1





    In your code, there is no need to store emitter as a member, so you can simply accept it is a parameter as well.

    – SergeyA
    8 hours ago











  • You can make the constructor a templated function instead, and type-erase it into a std::function class member.

    – Sam Varshavchik
    8 hours ago






  • 3





    @SamVarshavchik: what would the signature of that std::function be?

    – Vittorio Romeo
    8 hours ago











  • The types of parameters the lambda takes, and its return value.

    – Sam Varshavchik
    7 hours ago






  • 1





    Type-erase the parameter to the lambda itself. At some point, somewhere, the type must be known, or determined someway. Nothing more can really be said about this, is is too vague, at this point.

    – Sam Varshavchik
    7 hours ago












  • 1





    In your code, there is no need to store emitter as a member, so you can simply accept it is a parameter as well.

    – SergeyA
    8 hours ago











  • You can make the constructor a templated function instead, and type-erase it into a std::function class member.

    – Sam Varshavchik
    8 hours ago






  • 3





    @SamVarshavchik: what would the signature of that std::function be?

    – Vittorio Romeo
    8 hours ago











  • The types of parameters the lambda takes, and its return value.

    – Sam Varshavchik
    7 hours ago






  • 1





    Type-erase the parameter to the lambda itself. At some point, somewhere, the type must be known, or determined someway. Nothing more can really be said about this, is is too vague, at this point.

    – Sam Varshavchik
    7 hours ago







1




1





In your code, there is no need to store emitter as a member, so you can simply accept it is a parameter as well.

– SergeyA
8 hours ago





In your code, there is no need to store emitter as a member, so you can simply accept it is a parameter as well.

– SergeyA
8 hours ago













You can make the constructor a templated function instead, and type-erase it into a std::function class member.

– Sam Varshavchik
8 hours ago





You can make the constructor a templated function instead, and type-erase it into a std::function class member.

– Sam Varshavchik
8 hours ago




3




3





@SamVarshavchik: what would the signature of that std::function be?

– Vittorio Romeo
8 hours ago





@SamVarshavchik: what would the signature of that std::function be?

– Vittorio Romeo
8 hours ago













The types of parameters the lambda takes, and its return value.

– Sam Varshavchik
7 hours ago





The types of parameters the lambda takes, and its return value.

– Sam Varshavchik
7 hours ago




1




1





Type-erase the parameter to the lambda itself. At some point, somewhere, the type must be known, or determined someway. Nothing more can really be said about this, is is too vague, at this point.

– Sam Varshavchik
7 hours ago





Type-erase the parameter to the lambda itself. At some point, somewhere, the type must be known, or determined someway. Nothing more can really be said about this, is is too vague, at this point.

– Sam Varshavchik
7 hours ago












4 Answers
4






active

oldest

votes


















4














This simplest solution is to make Emitter a parameter to process:



struct Processor 
template <typename T, typename EmitterFn>
void process(T&& value, EmitterFn emit)
cout << "some processing... ";
emit(std::forward<T>(value));


;



However, if it must be a member of Processor and you can enumerate the possible function signatures, you can use some kind of type erasure. std::function or the proposed std::function_ref won't work because they only allow a single function signature, but we can write our own overloaded_function_ref:



template <typename Derived, typename Sig>
class function_ref_impl;

template <typename Derived, typename R, typename... Args>
class function_ref_impl<Derived, R(Args...)>
using fn_t = R(*)(void const*, Args...);

public:
auto operator()(Args... args) const -> R
return fn(static_cast<Derived const&>(*this).object, std::forward<Args>(args)...);


protected:
template <typename F,
std::enable_if_t<!std::is_base_of<function_ref_impl, F>::value, int> = 0>
explicit function_ref_impl(F const& f)
: fn[](void const* self, Args... args) -> R
return (*static_cast<F const*>(self))(std::forward<Args>(args)...);



private:
fn_t fn;
;

template <typename... Sig>
class overloaded_function_ref
: public function_ref_impl<overloaded_function_ref<Sig...>, Sig>...

public:
template <typename F,
std::enable_if_t<!std::is_base_of<overloaded_function_ref, F>::value, int> = 0>
overloaded_function_ref(F const& f)
: function_ref_impl<overloaded_function_ref, Sig>(f)...
, objectstd::addressof(f)


// Can be done pre-C++17, but it's not easy:
using function_ref_impl<overloaded_function_ref, Sig>::operator()...;

// This can be encapsulated with techniques such as the "passkey" idiom.
// Variadic friend expansion isn't a thing (`friend bases...`).
void const* object;
;


Live example



This does require C++17 for the using
/* base */::operator()...
, but that can be emulated in C++14; see the paper that introduced this feature: [P0195], or perhaps Boost HOF's match can be massaged to do this. This is also just a function reference and not an owning function.



Then we can write:



struct Processor 
template <typename T>
void process(T&& value)
cout << "some processing... ";
emit(std::forward<T>(value));


using emitter_t = overloaded_function_ref<
void(int),
void(double),
void(char*),
void(char const*)
>;

emitter_t emit;
;


Demo






share|improve this answer
































    3














    IMHO: Inheritance is here for that.



    #include <iostream>
    #include <utility>

    using namespace std;

    struct BaseEmitter
    virtual void e(int) =0;
    virtual void e(double)=0;
    virtual void e(char*)=0;
    virtual void e(const char*)=0;
    ;

    struct Emitter :public BaseEmitter
    virtual void e(int) cout << "emitting intn";
    virtual void e(double) cout << "emitting doublen";
    virtual void e(char*) cout << "emitting char*n";
    virtual void e(const char*) cout << "emitting const char*n";
    ;

    struct Processor
    BaseEmitter& e_;
    Processor(BaseEmitter& e) : e_(e)

    template <typename T>
    void process(T&& value)
    cout << "some processing... ";
    e_(std::forward<T>(value));

    ;


    int main()
    Emitter em;
    auto p = Processor(em);
    p.process(1);
    p.process("lol");
    return 0;






    share|improve this answer























    • This is a proposal to the motivation, not to the asked question.

      – Mel Viso Martinez
      6 hours ago


















    1















    Is it possible to pass generic lambda as non-template argument




    It is not possible to declare a non-template function that accepts a lambda as an argument. The type of a lambda is anonymous: It has no name. It is not possible to write a function declaration that accepts an argument of an anonymous type.



    The type of the lambda can be deduced, which is why lambdas can be passed into function templates whose argument types are deduced.



    While this answers the question, it does not offer a solution. I don't think a solution is going to be simple.






    share|improve this answer

























    • "It is not possible to declare a non-template function that accepts a lambda as an argument." Except you can have an implicit conversion to a non-template type, e.g. std::function or the upcoming std::function_ref

      – Justin
      8 hours ago






    • 1





      But that std::function wrapper can only be used to call one particular signature of the lambda, which is insufficient here...

      – Max Langhof
      8 hours ago












    • @MaxLanghof Hmm, yeah. Function wrapper might not be of use here.

      – eerorika
      8 hours ago






    • 2





      @MaxLanghof You could write your own which accepts multiple signatures, as long as you can enumerate the possible signatures. E.g. overloaded_function_ref<void(int), void(double), void(char*), void(char const*)>

      – Justin
      8 hours ago







    • 1





      @Justin: sadly std::function_ref was delayed to C++23.

      – Vittorio Romeo
      8 hours ago



















    1














    If you are willing to pay a high runtime cost in exchange for minimal constraints, you can use std::function with std::any (for C++14, use boost::any):



    #include <iostream>
    #include <utility>
    #include <any>
    #include <functional>

    struct Processor
    Processor(std::function<void(std::any)> e) : e_e

    template <typename T>
    void process(T&& value)
    std::cout << "some processing... ";
    e_(std::forward<T>(value));


    std::function<void(std::any)> e_;
    ;

    struct Emitter
    void e(int) std::cout << "emitting intn";
    void e(double) std::cout << "emitting doublen";
    void e(char*) std::cout << "emitting char*n";
    void e(const char*) std::cout << "emitting const char*n";
    ;

    int main()
    Emitter em;
    auto p = Processor(
    [&em](std::any any)
    // This if-else chain isn't that cheap, but it's about the best
    // we can do. Alternatives include:
    // - Hashmap from `std::type_index` (possibly using a perfect hash)
    // to a function pointer that implements this.
    // - Custom `any` implementation which allows "visitation":
    //
    // any.visit<int, double, char*, char const*>([&em] (auto it)
    // em.e(it);
    // );
    if (auto* i = std::any_cast<int>(&any))
    em.e(*i);
    else if (auto* d = std::any_cast<double>(&any))
    em.e(*d);
    else if (auto* cstr = std::any_cast<char*>(&any))
    em.e(*cstr);
    else
    em.e(std::any_cast<char const*>(any));


    );


    p.process(1);
    p.process("lol");
    return 0;



    std::any and std::function are both owning type erased wrappers. You may have heap allocations for this, or you might fit inside their small object optimization. You will have virtual function calls (or equivalent).



    Compiler Explorer link






    share|improve this answer



























      Your Answer






      StackExchange.ifUsing("editor", function ()
      StackExchange.using("externalEditor", function ()
      StackExchange.using("snippets", function ()
      StackExchange.snippets.init();
      );
      );
      , "code-snippets");

      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "1"
      ;
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function()
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled)
      StackExchange.using("snippets", function()
      createEditor();
      );

      else
      createEditor();

      );

      function createEditor()
      StackExchange.prepareEditor(
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader:
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      ,
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      );



      );













      draft saved

      draft discarded


















      StackExchange.ready(
      function ()
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57149664%2fis-it-possible-to-pass-generic-lambda-as-non-template-argument%23new-answer', 'question_page');

      );

      Post as a guest















      Required, but never shown

























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      4














      This simplest solution is to make Emitter a parameter to process:



      struct Processor 
      template <typename T, typename EmitterFn>
      void process(T&& value, EmitterFn emit)
      cout << "some processing... ";
      emit(std::forward<T>(value));


      ;



      However, if it must be a member of Processor and you can enumerate the possible function signatures, you can use some kind of type erasure. std::function or the proposed std::function_ref won't work because they only allow a single function signature, but we can write our own overloaded_function_ref:



      template <typename Derived, typename Sig>
      class function_ref_impl;

      template <typename Derived, typename R, typename... Args>
      class function_ref_impl<Derived, R(Args...)>
      using fn_t = R(*)(void const*, Args...);

      public:
      auto operator()(Args... args) const -> R
      return fn(static_cast<Derived const&>(*this).object, std::forward<Args>(args)...);


      protected:
      template <typename F,
      std::enable_if_t<!std::is_base_of<function_ref_impl, F>::value, int> = 0>
      explicit function_ref_impl(F const& f)
      : fn[](void const* self, Args... args) -> R
      return (*static_cast<F const*>(self))(std::forward<Args>(args)...);



      private:
      fn_t fn;
      ;

      template <typename... Sig>
      class overloaded_function_ref
      : public function_ref_impl<overloaded_function_ref<Sig...>, Sig>...

      public:
      template <typename F,
      std::enable_if_t<!std::is_base_of<overloaded_function_ref, F>::value, int> = 0>
      overloaded_function_ref(F const& f)
      : function_ref_impl<overloaded_function_ref, Sig>(f)...
      , objectstd::addressof(f)


      // Can be done pre-C++17, but it's not easy:
      using function_ref_impl<overloaded_function_ref, Sig>::operator()...;

      // This can be encapsulated with techniques such as the "passkey" idiom.
      // Variadic friend expansion isn't a thing (`friend bases...`).
      void const* object;
      ;


      Live example



      This does require C++17 for the using
      /* base */::operator()...
      , but that can be emulated in C++14; see the paper that introduced this feature: [P0195], or perhaps Boost HOF's match can be massaged to do this. This is also just a function reference and not an owning function.



      Then we can write:



      struct Processor 
      template <typename T>
      void process(T&& value)
      cout << "some processing... ";
      emit(std::forward<T>(value));


      using emitter_t = overloaded_function_ref<
      void(int),
      void(double),
      void(char*),
      void(char const*)
      >;

      emitter_t emit;
      ;


      Demo






      share|improve this answer





























        4














        This simplest solution is to make Emitter a parameter to process:



        struct Processor 
        template <typename T, typename EmitterFn>
        void process(T&& value, EmitterFn emit)
        cout << "some processing... ";
        emit(std::forward<T>(value));


        ;



        However, if it must be a member of Processor and you can enumerate the possible function signatures, you can use some kind of type erasure. std::function or the proposed std::function_ref won't work because they only allow a single function signature, but we can write our own overloaded_function_ref:



        template <typename Derived, typename Sig>
        class function_ref_impl;

        template <typename Derived, typename R, typename... Args>
        class function_ref_impl<Derived, R(Args...)>
        using fn_t = R(*)(void const*, Args...);

        public:
        auto operator()(Args... args) const -> R
        return fn(static_cast<Derived const&>(*this).object, std::forward<Args>(args)...);


        protected:
        template <typename F,
        std::enable_if_t<!std::is_base_of<function_ref_impl, F>::value, int> = 0>
        explicit function_ref_impl(F const& f)
        : fn[](void const* self, Args... args) -> R
        return (*static_cast<F const*>(self))(std::forward<Args>(args)...);



        private:
        fn_t fn;
        ;

        template <typename... Sig>
        class overloaded_function_ref
        : public function_ref_impl<overloaded_function_ref<Sig...>, Sig>...

        public:
        template <typename F,
        std::enable_if_t<!std::is_base_of<overloaded_function_ref, F>::value, int> = 0>
        overloaded_function_ref(F const& f)
        : function_ref_impl<overloaded_function_ref, Sig>(f)...
        , objectstd::addressof(f)


        // Can be done pre-C++17, but it's not easy:
        using function_ref_impl<overloaded_function_ref, Sig>::operator()...;

        // This can be encapsulated with techniques such as the "passkey" idiom.
        // Variadic friend expansion isn't a thing (`friend bases...`).
        void const* object;
        ;


        Live example



        This does require C++17 for the using
        /* base */::operator()...
        , but that can be emulated in C++14; see the paper that introduced this feature: [P0195], or perhaps Boost HOF's match can be massaged to do this. This is also just a function reference and not an owning function.



        Then we can write:



        struct Processor 
        template <typename T>
        void process(T&& value)
        cout << "some processing... ";
        emit(std::forward<T>(value));


        using emitter_t = overloaded_function_ref<
        void(int),
        void(double),
        void(char*),
        void(char const*)
        >;

        emitter_t emit;
        ;


        Demo






        share|improve this answer



























          4












          4








          4







          This simplest solution is to make Emitter a parameter to process:



          struct Processor 
          template <typename T, typename EmitterFn>
          void process(T&& value, EmitterFn emit)
          cout << "some processing... ";
          emit(std::forward<T>(value));


          ;



          However, if it must be a member of Processor and you can enumerate the possible function signatures, you can use some kind of type erasure. std::function or the proposed std::function_ref won't work because they only allow a single function signature, but we can write our own overloaded_function_ref:



          template <typename Derived, typename Sig>
          class function_ref_impl;

          template <typename Derived, typename R, typename... Args>
          class function_ref_impl<Derived, R(Args...)>
          using fn_t = R(*)(void const*, Args...);

          public:
          auto operator()(Args... args) const -> R
          return fn(static_cast<Derived const&>(*this).object, std::forward<Args>(args)...);


          protected:
          template <typename F,
          std::enable_if_t<!std::is_base_of<function_ref_impl, F>::value, int> = 0>
          explicit function_ref_impl(F const& f)
          : fn[](void const* self, Args... args) -> R
          return (*static_cast<F const*>(self))(std::forward<Args>(args)...);



          private:
          fn_t fn;
          ;

          template <typename... Sig>
          class overloaded_function_ref
          : public function_ref_impl<overloaded_function_ref<Sig...>, Sig>...

          public:
          template <typename F,
          std::enable_if_t<!std::is_base_of<overloaded_function_ref, F>::value, int> = 0>
          overloaded_function_ref(F const& f)
          : function_ref_impl<overloaded_function_ref, Sig>(f)...
          , objectstd::addressof(f)


          // Can be done pre-C++17, but it's not easy:
          using function_ref_impl<overloaded_function_ref, Sig>::operator()...;

          // This can be encapsulated with techniques such as the "passkey" idiom.
          // Variadic friend expansion isn't a thing (`friend bases...`).
          void const* object;
          ;


          Live example



          This does require C++17 for the using
          /* base */::operator()...
          , but that can be emulated in C++14; see the paper that introduced this feature: [P0195], or perhaps Boost HOF's match can be massaged to do this. This is also just a function reference and not an owning function.



          Then we can write:



          struct Processor 
          template <typename T>
          void process(T&& value)
          cout << "some processing... ";
          emit(std::forward<T>(value));


          using emitter_t = overloaded_function_ref<
          void(int),
          void(double),
          void(char*),
          void(char const*)
          >;

          emitter_t emit;
          ;


          Demo






          share|improve this answer















          This simplest solution is to make Emitter a parameter to process:



          struct Processor 
          template <typename T, typename EmitterFn>
          void process(T&& value, EmitterFn emit)
          cout << "some processing... ";
          emit(std::forward<T>(value));


          ;



          However, if it must be a member of Processor and you can enumerate the possible function signatures, you can use some kind of type erasure. std::function or the proposed std::function_ref won't work because they only allow a single function signature, but we can write our own overloaded_function_ref:



          template <typename Derived, typename Sig>
          class function_ref_impl;

          template <typename Derived, typename R, typename... Args>
          class function_ref_impl<Derived, R(Args...)>
          using fn_t = R(*)(void const*, Args...);

          public:
          auto operator()(Args... args) const -> R
          return fn(static_cast<Derived const&>(*this).object, std::forward<Args>(args)...);


          protected:
          template <typename F,
          std::enable_if_t<!std::is_base_of<function_ref_impl, F>::value, int> = 0>
          explicit function_ref_impl(F const& f)
          : fn[](void const* self, Args... args) -> R
          return (*static_cast<F const*>(self))(std::forward<Args>(args)...);



          private:
          fn_t fn;
          ;

          template <typename... Sig>
          class overloaded_function_ref
          : public function_ref_impl<overloaded_function_ref<Sig...>, Sig>...

          public:
          template <typename F,
          std::enable_if_t<!std::is_base_of<overloaded_function_ref, F>::value, int> = 0>
          overloaded_function_ref(F const& f)
          : function_ref_impl<overloaded_function_ref, Sig>(f)...
          , objectstd::addressof(f)


          // Can be done pre-C++17, but it's not easy:
          using function_ref_impl<overloaded_function_ref, Sig>::operator()...;

          // This can be encapsulated with techniques such as the "passkey" idiom.
          // Variadic friend expansion isn't a thing (`friend bases...`).
          void const* object;
          ;


          Live example



          This does require C++17 for the using
          /* base */::operator()...
          , but that can be emulated in C++14; see the paper that introduced this feature: [P0195], or perhaps Boost HOF's match can be massaged to do this. This is also just a function reference and not an owning function.



          Then we can write:



          struct Processor 
          template <typename T>
          void process(T&& value)
          cout << "some processing... ";
          emit(std::forward<T>(value));


          using emitter_t = overloaded_function_ref<
          void(int),
          void(double),
          void(char*),
          void(char const*)
          >;

          emitter_t emit;
          ;


          Demo







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited 7 hours ago

























          answered 7 hours ago









          JustinJustin

          14.8k9 gold badges60 silver badges104 bronze badges




          14.8k9 gold badges60 silver badges104 bronze badges























              3














              IMHO: Inheritance is here for that.



              #include <iostream>
              #include <utility>

              using namespace std;

              struct BaseEmitter
              virtual void e(int) =0;
              virtual void e(double)=0;
              virtual void e(char*)=0;
              virtual void e(const char*)=0;
              ;

              struct Emitter :public BaseEmitter
              virtual void e(int) cout << "emitting intn";
              virtual void e(double) cout << "emitting doublen";
              virtual void e(char*) cout << "emitting char*n";
              virtual void e(const char*) cout << "emitting const char*n";
              ;

              struct Processor
              BaseEmitter& e_;
              Processor(BaseEmitter& e) : e_(e)

              template <typename T>
              void process(T&& value)
              cout << "some processing... ";
              e_(std::forward<T>(value));

              ;


              int main()
              Emitter em;
              auto p = Processor(em);
              p.process(1);
              p.process("lol");
              return 0;






              share|improve this answer























              • This is a proposal to the motivation, not to the asked question.

                – Mel Viso Martinez
                6 hours ago















              3














              IMHO: Inheritance is here for that.



              #include <iostream>
              #include <utility>

              using namespace std;

              struct BaseEmitter
              virtual void e(int) =0;
              virtual void e(double)=0;
              virtual void e(char*)=0;
              virtual void e(const char*)=0;
              ;

              struct Emitter :public BaseEmitter
              virtual void e(int) cout << "emitting intn";
              virtual void e(double) cout << "emitting doublen";
              virtual void e(char*) cout << "emitting char*n";
              virtual void e(const char*) cout << "emitting const char*n";
              ;

              struct Processor
              BaseEmitter& e_;
              Processor(BaseEmitter& e) : e_(e)

              template <typename T>
              void process(T&& value)
              cout << "some processing... ";
              e_(std::forward<T>(value));

              ;


              int main()
              Emitter em;
              auto p = Processor(em);
              p.process(1);
              p.process("lol");
              return 0;






              share|improve this answer























              • This is a proposal to the motivation, not to the asked question.

                – Mel Viso Martinez
                6 hours ago













              3












              3








              3







              IMHO: Inheritance is here for that.



              #include <iostream>
              #include <utility>

              using namespace std;

              struct BaseEmitter
              virtual void e(int) =0;
              virtual void e(double)=0;
              virtual void e(char*)=0;
              virtual void e(const char*)=0;
              ;

              struct Emitter :public BaseEmitter
              virtual void e(int) cout << "emitting intn";
              virtual void e(double) cout << "emitting doublen";
              virtual void e(char*) cout << "emitting char*n";
              virtual void e(const char*) cout << "emitting const char*n";
              ;

              struct Processor
              BaseEmitter& e_;
              Processor(BaseEmitter& e) : e_(e)

              template <typename T>
              void process(T&& value)
              cout << "some processing... ";
              e_(std::forward<T>(value));

              ;


              int main()
              Emitter em;
              auto p = Processor(em);
              p.process(1);
              p.process("lol");
              return 0;






              share|improve this answer













              IMHO: Inheritance is here for that.



              #include <iostream>
              #include <utility>

              using namespace std;

              struct BaseEmitter
              virtual void e(int) =0;
              virtual void e(double)=0;
              virtual void e(char*)=0;
              virtual void e(const char*)=0;
              ;

              struct Emitter :public BaseEmitter
              virtual void e(int) cout << "emitting intn";
              virtual void e(double) cout << "emitting doublen";
              virtual void e(char*) cout << "emitting char*n";
              virtual void e(const char*) cout << "emitting const char*n";
              ;

              struct Processor
              BaseEmitter& e_;
              Processor(BaseEmitter& e) : e_(e)

              template <typename T>
              void process(T&& value)
              cout << "some processing... ";
              e_(std::forward<T>(value));

              ;


              int main()
              Emitter em;
              auto p = Processor(em);
              p.process(1);
              p.process("lol");
              return 0;







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 6 hours ago









              Mel Viso MartinezMel Viso Martinez

              5154 silver badges8 bronze badges




              5154 silver badges8 bronze badges












              • This is a proposal to the motivation, not to the asked question.

                – Mel Viso Martinez
                6 hours ago

















              • This is a proposal to the motivation, not to the asked question.

                – Mel Viso Martinez
                6 hours ago
















              This is a proposal to the motivation, not to the asked question.

              – Mel Viso Martinez
              6 hours ago





              This is a proposal to the motivation, not to the asked question.

              – Mel Viso Martinez
              6 hours ago











              1















              Is it possible to pass generic lambda as non-template argument




              It is not possible to declare a non-template function that accepts a lambda as an argument. The type of a lambda is anonymous: It has no name. It is not possible to write a function declaration that accepts an argument of an anonymous type.



              The type of the lambda can be deduced, which is why lambdas can be passed into function templates whose argument types are deduced.



              While this answers the question, it does not offer a solution. I don't think a solution is going to be simple.






              share|improve this answer

























              • "It is not possible to declare a non-template function that accepts a lambda as an argument." Except you can have an implicit conversion to a non-template type, e.g. std::function or the upcoming std::function_ref

                – Justin
                8 hours ago






              • 1





                But that std::function wrapper can only be used to call one particular signature of the lambda, which is insufficient here...

                – Max Langhof
                8 hours ago












              • @MaxLanghof Hmm, yeah. Function wrapper might not be of use here.

                – eerorika
                8 hours ago






              • 2





                @MaxLanghof You could write your own which accepts multiple signatures, as long as you can enumerate the possible signatures. E.g. overloaded_function_ref<void(int), void(double), void(char*), void(char const*)>

                – Justin
                8 hours ago







              • 1





                @Justin: sadly std::function_ref was delayed to C++23.

                – Vittorio Romeo
                8 hours ago
















              1















              Is it possible to pass generic lambda as non-template argument




              It is not possible to declare a non-template function that accepts a lambda as an argument. The type of a lambda is anonymous: It has no name. It is not possible to write a function declaration that accepts an argument of an anonymous type.



              The type of the lambda can be deduced, which is why lambdas can be passed into function templates whose argument types are deduced.



              While this answers the question, it does not offer a solution. I don't think a solution is going to be simple.






              share|improve this answer

























              • "It is not possible to declare a non-template function that accepts a lambda as an argument." Except you can have an implicit conversion to a non-template type, e.g. std::function or the upcoming std::function_ref

                – Justin
                8 hours ago






              • 1





                But that std::function wrapper can only be used to call one particular signature of the lambda, which is insufficient here...

                – Max Langhof
                8 hours ago












              • @MaxLanghof Hmm, yeah. Function wrapper might not be of use here.

                – eerorika
                8 hours ago






              • 2





                @MaxLanghof You could write your own which accepts multiple signatures, as long as you can enumerate the possible signatures. E.g. overloaded_function_ref<void(int), void(double), void(char*), void(char const*)>

                – Justin
                8 hours ago







              • 1





                @Justin: sadly std::function_ref was delayed to C++23.

                – Vittorio Romeo
                8 hours ago














              1












              1








              1








              Is it possible to pass generic lambda as non-template argument




              It is not possible to declare a non-template function that accepts a lambda as an argument. The type of a lambda is anonymous: It has no name. It is not possible to write a function declaration that accepts an argument of an anonymous type.



              The type of the lambda can be deduced, which is why lambdas can be passed into function templates whose argument types are deduced.



              While this answers the question, it does not offer a solution. I don't think a solution is going to be simple.






              share|improve this answer
















              Is it possible to pass generic lambda as non-template argument




              It is not possible to declare a non-template function that accepts a lambda as an argument. The type of a lambda is anonymous: It has no name. It is not possible to write a function declaration that accepts an argument of an anonymous type.



              The type of the lambda can be deduced, which is why lambdas can be passed into function templates whose argument types are deduced.



              While this answers the question, it does not offer a solution. I don't think a solution is going to be simple.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited 7 hours ago

























              answered 8 hours ago









              eerorikaeerorika

              101k6 gold badges80 silver badges156 bronze badges




              101k6 gold badges80 silver badges156 bronze badges












              • "It is not possible to declare a non-template function that accepts a lambda as an argument." Except you can have an implicit conversion to a non-template type, e.g. std::function or the upcoming std::function_ref

                – Justin
                8 hours ago






              • 1





                But that std::function wrapper can only be used to call one particular signature of the lambda, which is insufficient here...

                – Max Langhof
                8 hours ago












              • @MaxLanghof Hmm, yeah. Function wrapper might not be of use here.

                – eerorika
                8 hours ago






              • 2





                @MaxLanghof You could write your own which accepts multiple signatures, as long as you can enumerate the possible signatures. E.g. overloaded_function_ref<void(int), void(double), void(char*), void(char const*)>

                – Justin
                8 hours ago







              • 1





                @Justin: sadly std::function_ref was delayed to C++23.

                – Vittorio Romeo
                8 hours ago


















              • "It is not possible to declare a non-template function that accepts a lambda as an argument." Except you can have an implicit conversion to a non-template type, e.g. std::function or the upcoming std::function_ref

                – Justin
                8 hours ago






              • 1





                But that std::function wrapper can only be used to call one particular signature of the lambda, which is insufficient here...

                – Max Langhof
                8 hours ago












              • @MaxLanghof Hmm, yeah. Function wrapper might not be of use here.

                – eerorika
                8 hours ago






              • 2





                @MaxLanghof You could write your own which accepts multiple signatures, as long as you can enumerate the possible signatures. E.g. overloaded_function_ref<void(int), void(double), void(char*), void(char const*)>

                – Justin
                8 hours ago







              • 1





                @Justin: sadly std::function_ref was delayed to C++23.

                – Vittorio Romeo
                8 hours ago

















              "It is not possible to declare a non-template function that accepts a lambda as an argument." Except you can have an implicit conversion to a non-template type, e.g. std::function or the upcoming std::function_ref

              – Justin
              8 hours ago





              "It is not possible to declare a non-template function that accepts a lambda as an argument." Except you can have an implicit conversion to a non-template type, e.g. std::function or the upcoming std::function_ref

              – Justin
              8 hours ago




              1




              1





              But that std::function wrapper can only be used to call one particular signature of the lambda, which is insufficient here...

              – Max Langhof
              8 hours ago






              But that std::function wrapper can only be used to call one particular signature of the lambda, which is insufficient here...

              – Max Langhof
              8 hours ago














              @MaxLanghof Hmm, yeah. Function wrapper might not be of use here.

              – eerorika
              8 hours ago





              @MaxLanghof Hmm, yeah. Function wrapper might not be of use here.

              – eerorika
              8 hours ago




              2




              2





              @MaxLanghof You could write your own which accepts multiple signatures, as long as you can enumerate the possible signatures. E.g. overloaded_function_ref<void(int), void(double), void(char*), void(char const*)>

              – Justin
              8 hours ago






              @MaxLanghof You could write your own which accepts multiple signatures, as long as you can enumerate the possible signatures. E.g. overloaded_function_ref<void(int), void(double), void(char*), void(char const*)>

              – Justin
              8 hours ago





              1




              1





              @Justin: sadly std::function_ref was delayed to C++23.

              – Vittorio Romeo
              8 hours ago






              @Justin: sadly std::function_ref was delayed to C++23.

              – Vittorio Romeo
              8 hours ago












              1














              If you are willing to pay a high runtime cost in exchange for minimal constraints, you can use std::function with std::any (for C++14, use boost::any):



              #include <iostream>
              #include <utility>
              #include <any>
              #include <functional>

              struct Processor
              Processor(std::function<void(std::any)> e) : e_e

              template <typename T>
              void process(T&& value)
              std::cout << "some processing... ";
              e_(std::forward<T>(value));


              std::function<void(std::any)> e_;
              ;

              struct Emitter
              void e(int) std::cout << "emitting intn";
              void e(double) std::cout << "emitting doublen";
              void e(char*) std::cout << "emitting char*n";
              void e(const char*) std::cout << "emitting const char*n";
              ;

              int main()
              Emitter em;
              auto p = Processor(
              [&em](std::any any)
              // This if-else chain isn't that cheap, but it's about the best
              // we can do. Alternatives include:
              // - Hashmap from `std::type_index` (possibly using a perfect hash)
              // to a function pointer that implements this.
              // - Custom `any` implementation which allows "visitation":
              //
              // any.visit<int, double, char*, char const*>([&em] (auto it)
              // em.e(it);
              // );
              if (auto* i = std::any_cast<int>(&any))
              em.e(*i);
              else if (auto* d = std::any_cast<double>(&any))
              em.e(*d);
              else if (auto* cstr = std::any_cast<char*>(&any))
              em.e(*cstr);
              else
              em.e(std::any_cast<char const*>(any));


              );


              p.process(1);
              p.process("lol");
              return 0;



              std::any and std::function are both owning type erased wrappers. You may have heap allocations for this, or you might fit inside their small object optimization. You will have virtual function calls (or equivalent).



              Compiler Explorer link






              share|improve this answer





























                1














                If you are willing to pay a high runtime cost in exchange for minimal constraints, you can use std::function with std::any (for C++14, use boost::any):



                #include <iostream>
                #include <utility>
                #include <any>
                #include <functional>

                struct Processor
                Processor(std::function<void(std::any)> e) : e_e

                template <typename T>
                void process(T&& value)
                std::cout << "some processing... ";
                e_(std::forward<T>(value));


                std::function<void(std::any)> e_;
                ;

                struct Emitter
                void e(int) std::cout << "emitting intn";
                void e(double) std::cout << "emitting doublen";
                void e(char*) std::cout << "emitting char*n";
                void e(const char*) std::cout << "emitting const char*n";
                ;

                int main()
                Emitter em;
                auto p = Processor(
                [&em](std::any any)
                // This if-else chain isn't that cheap, but it's about the best
                // we can do. Alternatives include:
                // - Hashmap from `std::type_index` (possibly using a perfect hash)
                // to a function pointer that implements this.
                // - Custom `any` implementation which allows "visitation":
                //
                // any.visit<int, double, char*, char const*>([&em] (auto it)
                // em.e(it);
                // );
                if (auto* i = std::any_cast<int>(&any))
                em.e(*i);
                else if (auto* d = std::any_cast<double>(&any))
                em.e(*d);
                else if (auto* cstr = std::any_cast<char*>(&any))
                em.e(*cstr);
                else
                em.e(std::any_cast<char const*>(any));


                );


                p.process(1);
                p.process("lol");
                return 0;



                std::any and std::function are both owning type erased wrappers. You may have heap allocations for this, or you might fit inside their small object optimization. You will have virtual function calls (or equivalent).



                Compiler Explorer link






                share|improve this answer



























                  1












                  1








                  1







                  If you are willing to pay a high runtime cost in exchange for minimal constraints, you can use std::function with std::any (for C++14, use boost::any):



                  #include <iostream>
                  #include <utility>
                  #include <any>
                  #include <functional>

                  struct Processor
                  Processor(std::function<void(std::any)> e) : e_e

                  template <typename T>
                  void process(T&& value)
                  std::cout << "some processing... ";
                  e_(std::forward<T>(value));


                  std::function<void(std::any)> e_;
                  ;

                  struct Emitter
                  void e(int) std::cout << "emitting intn";
                  void e(double) std::cout << "emitting doublen";
                  void e(char*) std::cout << "emitting char*n";
                  void e(const char*) std::cout << "emitting const char*n";
                  ;

                  int main()
                  Emitter em;
                  auto p = Processor(
                  [&em](std::any any)
                  // This if-else chain isn't that cheap, but it's about the best
                  // we can do. Alternatives include:
                  // - Hashmap from `std::type_index` (possibly using a perfect hash)
                  // to a function pointer that implements this.
                  // - Custom `any` implementation which allows "visitation":
                  //
                  // any.visit<int, double, char*, char const*>([&em] (auto it)
                  // em.e(it);
                  // );
                  if (auto* i = std::any_cast<int>(&any))
                  em.e(*i);
                  else if (auto* d = std::any_cast<double>(&any))
                  em.e(*d);
                  else if (auto* cstr = std::any_cast<char*>(&any))
                  em.e(*cstr);
                  else
                  em.e(std::any_cast<char const*>(any));


                  );


                  p.process(1);
                  p.process("lol");
                  return 0;



                  std::any and std::function are both owning type erased wrappers. You may have heap allocations for this, or you might fit inside their small object optimization. You will have virtual function calls (or equivalent).



                  Compiler Explorer link






                  share|improve this answer















                  If you are willing to pay a high runtime cost in exchange for minimal constraints, you can use std::function with std::any (for C++14, use boost::any):



                  #include <iostream>
                  #include <utility>
                  #include <any>
                  #include <functional>

                  struct Processor
                  Processor(std::function<void(std::any)> e) : e_e

                  template <typename T>
                  void process(T&& value)
                  std::cout << "some processing... ";
                  e_(std::forward<T>(value));


                  std::function<void(std::any)> e_;
                  ;

                  struct Emitter
                  void e(int) std::cout << "emitting intn";
                  void e(double) std::cout << "emitting doublen";
                  void e(char*) std::cout << "emitting char*n";
                  void e(const char*) std::cout << "emitting const char*n";
                  ;

                  int main()
                  Emitter em;
                  auto p = Processor(
                  [&em](std::any any)
                  // This if-else chain isn't that cheap, but it's about the best
                  // we can do. Alternatives include:
                  // - Hashmap from `std::type_index` (possibly using a perfect hash)
                  // to a function pointer that implements this.
                  // - Custom `any` implementation which allows "visitation":
                  //
                  // any.visit<int, double, char*, char const*>([&em] (auto it)
                  // em.e(it);
                  // );
                  if (auto* i = std::any_cast<int>(&any))
                  em.e(*i);
                  else if (auto* d = std::any_cast<double>(&any))
                  em.e(*d);
                  else if (auto* cstr = std::any_cast<char*>(&any))
                  em.e(*cstr);
                  else
                  em.e(std::any_cast<char const*>(any));


                  );


                  p.process(1);
                  p.process("lol");
                  return 0;



                  std::any and std::function are both owning type erased wrappers. You may have heap allocations for this, or you might fit inside their small object optimization. You will have virtual function calls (or equivalent).



                  Compiler Explorer link







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited 6 hours ago

























                  answered 7 hours ago









                  JustinJustin

                  14.8k9 gold badges60 silver badges104 bronze badges




                  14.8k9 gold badges60 silver badges104 bronze badges



























                      draft saved

                      draft discarded
















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid


                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.

                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f57149664%2fis-it-possible-to-pass-generic-lambda-as-non-template-argument%23new-answer', 'question_page');

                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

                      Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

                      Tom Holland Mục lục Đầu đời và giáo dục | Sự nghiệp | Cuộc sống cá nhân | Phim tham gia | Giải thưởng và đề cử | Chú thích | Liên kết ngoài | Trình đơn chuyển hướngProfile“Person Details for Thomas Stanley Holland, "England and Wales Birth Registration Index, 1837-2008" — FamilySearch.org”"Meet Tom Holland... the 16-year-old star of The Impossible""Schoolboy actor Tom Holland finds himself in Oscar contention for role in tsunami drama"“Naomi Watts on the Prince William and Harry's reaction to her film about the late Princess Diana”lưu trữ"Holland and Pflueger Are West End's Two New 'Billy Elliots'""I'm so envious of my son, the movie star! British writer Dominic Holland's spent 20 years trying to crack Hollywood - but he's been beaten to it by a very unlikely rival"“Richard and Margaret Povey of Jersey, Channel Islands, UK: Information about Thomas Stanley Holland”"Tom Holland to play Billy Elliot""New Billy Elliot leaving the garage"Billy Elliot the Musical - Tom Holland - Billy"A Tale of four Billys: Tom Holland""The Feel Good Factor""Thames Christian College schoolboys join Myleene Klass for The Feelgood Factor""Government launches £600,000 arts bursaries pilot""BILLY's Chapman, Holland, Gardner & Jackson-Keen Visit Prime Minister""Elton John 'blown away' by Billy Elliot fifth birthday" (video with John's interview and fragments of Holland's performance)"First News interviews Arrietty's Tom Holland"“33rd Critics' Circle Film Awards winners”“National Board of Review Current Awards”Bản gốc"Ron Howard Whaling Tale 'In The Heart Of The Sea' Casts Tom Holland"“'Spider-Man' Finds Tom Holland to Star as New Web-Slinger”lưu trữ“Captain America: Civil War (2016)”“Film Review: ‘Captain America: Civil War’”lưu trữ“‘Captain America: Civil War’ review: Choose your own avenger”lưu trữ“The Lost City of Z reviews”“Sony Pictures and Marvel Studios Find Their 'Spider-Man' Star and Director”“‘Mary Magdalene’, ‘Current War’ & ‘Wind River’ Get 2017 Release Dates From Weinstein”“Lionsgate Unleashing Daisy Ridley & Tom Holland Starrer ‘Chaos Walking’ In Cannes”“PTA's 'Master' Leads Chicago Film Critics Nominations, UPDATED: Houston and Indiana Critics Nominations”“Nominaciones Goya 2013 Telecinco Cinema – ENG”“Jameson Empire Film Awards: Martin Freeman wins best actor for performance in The Hobbit”“34th Annual Young Artist Awards”Bản gốc“Teen Choice Awards 2016—Captain America: Civil War Leads Second Wave of Nominations”“BAFTA Film Award Nominations: ‘La La Land’ Leads Race”“Saturn Awards Nominations 2017: 'Rogue One,' 'Walking Dead' Lead”Tom HollandTom HollandTom HollandTom Hollandmedia.gettyimages.comWorldCat Identities300279794no20130442900000 0004 0355 42791085670554170004732cb16706349t(data)XX5557367