skip to Main Content

I have a base class with a vector of pointers, and I think to slide the vector outside this class, I wrote the for_each() method:

 class model {
   static std::vector<model*> models;
  ...
   public:
    template <class C>
    static void for_each(C *c,void (C::*f)(model *))
     {
      for (std::vector<model*>::iterator it=models.begin(); it!=models.end(); ++it) {
      c->f(*it);
     }
   ...
  }

I tryed to use for_each() in a member function:

void v_context::build_cmd()
{
 ...
 auto f1=[&](model* m)->void{commandBuffers.push_back(*(m->build_secondary_buffers(inheritanceInfo, pipelines.gltf)));};
 model::for_each<VulkanExample,void (VulkanExample::*)(model*)>(this,f1);
 ...
}

The compiler (gcc version 10.2.1 20210110 (Debian 10.2.1-6)), rightly returns the error:

error: cannot convert ‘v_context::build_cmd()::<lambda(model*)>’ to
‘void (v_context::)(model)’

note: initializing argument 2 of ‘static void model::for_each(C*, void
(C::)(model)) [with C=v_context]’

Is it possible? Does correct syntax template exist?

2

Answers


  1. The simplest is probably to make it even more generic:

    class model {
        static std::vector<model *> models;
    public:
        template <class Func>
        static void for_each(Func&& func) { // no instance needed
            for (auto ptr : models) {       // simplified loop
                func(ptr);
            }
        }
    };
    

    Then just capture [this] in the lambdas you use it with:

    void VulkanExample::build_cmd() {
        auto f1 = [this](model *m) {
            // ...
        };
        model::for_each(f1);
    }
    

    Demo

    Login or Signup to reply.
  2. You could use std::invoke to implement this logic. A class and a member function pointer this would require swapping the parameters, but otherwise this would allow you to pass any number of additional parameters before the model* parameter:

    class model
    {
    ...
    
        template <class F, class...Args>
        static void for_each(F&& f, Args&&...args)
        {
            for (auto p : models)
            {
                std::invoke(f, args..., p);
            }
        }
        ...
    
    };
    

    Example usages:

    struct Foo
    {
        void Bar(model*) {}
    };
    
    ...
    
    Foo foo;
    model::for_each(&Foo::Bar, foo);
    model::for_each([&](model* m)->void{commandBuffers.push_back(*(m->build_secondary_buffers(inheritanceInfo, pipelines.gltf)));});
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search