How to create a std :: vector function without explicitly defining functions?

I want to create a std :: vector object (or any other standard or custom container type) with custom and arbitrary function elements whose signatures are all the same.

It should be something like this:

// Define the functions and push them into a vector std::vector<????> MyFunctions; MyFunctions.push_back(double(int n, float f){ return (double) f / (double) n; }); MyFunctions.push_back(double(int n, float f){ return (double) sqrt((double) f) / (double) n; }); // ... MyFunctions.push_back(double(int n, float f){ return (double) (f * f) / (double) (n + 1); }); // Create an argument list std::vector<std::pair<int, float>> ArgumentList; // ... // Evaluate the functions with the given arguments // Suppose that it is guarantied that ArgumentList and MyFunctions are in the same size std::vector<double> Results; for (size_t i=0; i<MyFunctions.size(); i++) { Results.push_back(MyFunctions.at(i)(ArgumentList.at(i).first, ArgumentList.at(i).second)); } 

If possible, I do not want to explicitly define these functions, as shown below:

 class MyClass { public: void LoadFunctions() { std::vector<????> MyFunctions; MyFunctions.push_back(MyFoo_00); MyFunctions.push_back(MyFoo_01); MyFunctions.push_back(MyFoo_02); // ... MyFunctions.push_back(MyFoo_nn); } private: double MyFoo_00(int n, float f) { /* ... */ } double MyFoo_01(int n, float f) { /* ... */ } double MyFoo_02(int n, float f) { /* ... */ } // ... double MyFoo_nn(int n, float f) { /* ... */ } }; 

An implementation using some standard library tool (e.g. using std::function ) is fine. But a non-standard way to do this (for example, using Boost, QT or any other library or framework) is not preferred.

+4
source share
3 answers

Assuming your compiler is fairly modern, you can use the new std::function types and anonymous (lambda) functions introduced in C ++ 11:

 std::vector<std::function<double(int, float)>> MyFunctions; MyFunctions.push_back([](int n, float f) { return (double) f / (double) n; }); MyFunctions.push_back([](int n, float f) { return (double) sqrt((double) f) / (double) n; }); // ... MyFunctions.push_back([](int n, float f) { return (double) (f * f) / (double) (n + 1); }); 
+3
source

It looks like you want lambda functions . If your C ++ compiler implements this part of the C ++ 11 standard, you can use them directly. Otherwise, you can use Boost Phoenix or Boost Lambda .

+6
source

You can do this using std::function and lambdas:

 #include <vector> #include <functional> #include <iostream> #include <algorithm> #include <iterator> struct dispatcher { template <typename F, typename Pair> double operator()(const F& func, const Pair& p) const { return func(p.first, p.second); } }; int main() { std::vector<std::function<double(int,double)>> functions; functions.push_back([](int n, float f) { return double(f)/double(n); }); std::vector<std::pair<int, float>> args = {std::make_pair(1, 10.0f)}; std::vector<double> results; std::transform(functions.begin(), functions.end(), args.begin(), std::back_inserter(results), dispatcher()); std::copy(results.begin(), results.end(), std::ostream_iterator<double>(std::cout, "\n")); } 
+2
source

Source: https://habr.com/ru/post/1388186/


All Articles