简体   繁体   中英

How can I get the return of a function called from a vector std::vector that contains std::function

I have a structure that in the constructor receives an initialization list std::initializer_list<P...> of type parameter pack, that constructor is filled with lambda functions and they are saved in a std::vector<P...> point is how I get the return of those functions when traversing the vector calling each function here I leave an example of the structure and what I want to do

 #include <iostream>
#include <functional>
#include <initializer_list>
using namespace std;

struct my_type {
    my_type(){}
    my_type(string _value) : value(_value) {}
    string value = "test";
    string getValue(){return value;}
};


template<typename A, class...P>
struct struct_name {
  struct_name(std::initializer_list<P...> list)  : functions(list) {}
  std::vector<P...> functions;
  
  string value;
  my_type type;      

  string execute_functions(){
     for (size_t i = 0; i < functions.size(); i++)
    {
     value = functions[i](type);  // something like this, this does not work
    }
    return value;
    std::cout << value;
  }
};

typedef struct_name<std::function<void(my_type)>, std::function<void(my_type)>> _functions;


int main(int argc, char const *argv[])
{

    _functions object = {
      [](my_type var)->string{
        return var.getValue();
      },
      [](my_type var)->string{
        return var.getValue();
      },
    };

    return 0;
}

everything works perfect except the way to obtain those values, I totally don't know and no matter how hard I look I can't find answers

edit: I can't paste the complete code because it depends on many other classes and I tried to recreate that section, the type is parameter pack because it receives multiple types besides lambdas but in the example I just put it that way

If you are trying to process a value through a series of function you can just use std::accumulate :

#include <iostream>
#include <vector>
#include <functional>
#include <numeric>

int main()
{
  std::vector<std::function<float(float)>> functions = {
    [] (float f) { return f*f; },
    [] (float f) { return f + 2; }
  };
    
  float result = std::accumulate(functions.begin(), functions.end(), 1.5f, 
    [] (float v, const auto& lambda) {
      return lambda(v); 
    }
  );
    
  std::cout << 1.5f << " -> " << result << std::endl;

  return 0;
}

But a vector can only contain one specified type, so what you are trying to do with you parameter pack P... doesn't make much sense, if you want to process multiple values through multiple functions with different signatures you'd better try with something like std::tuple<std::function<T1(T2)>, std::function<T3(T4)>, ...> and pass multiple values to it.

You should be using std::tuple , if you want to store arbitrary callable objects.

You can combine std::index_sequence with a fold expression for calling the functions:

#include <iostream>
#include <string>
#include <tuple>
#include <utility>

using std::string;

struct my_type {
    my_type(){}
    my_type(string _value) : value(_value) {}
    string value = "test";
    string getValue(){return value;}
};

template<class...P>
struct struct_name {
    struct_name(P... args)
        : functions(args...)
    {}

    std::tuple<P...> functions;

    std::string value;
    my_type type;

    std::string execute_functions() {
        return execute_helper(std::make_index_sequence<sizeof...(P)>{});
    }
private:
    template<size_t ...Is>
    std::string execute_helper(std::index_sequence<Is...>)
    {
        ((value += std::get<Is>(functions)(type)), ...);
        return value;
    }
};

int main()
{
    struct_name foo(
        [](my_type var)->string {
            return var.getValue();
        },
        [](my_type var)->string {
            return var.getValue();
        });
    std::cout << foo.execute_functions() << '\n';
    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM