samedi 20 décembre 2014

Better solution for this, please?

To goal is to find a suitable helper function to avoid the repeated code here (this differs a lot from my production code, but the idea is the same):



#include <vector>

struct Object {
int num;
std::vector<int> get(Object*) const;
};

int foo (int a, int b) {return (a+1)*(b-1);}

std::vector<int> Object::get (Object* o) const {
std::vector<int> v;
if (num < 5) {
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
v.push_back (i + j + num);
}
else if (num < 10) {
const int a = o->num * (o->num - 1) * (o->num + 2);
const int b = o->num * (o->num - 3) * (o->num + 4);
for (int i = 0; i <= 10; i++)
for (int j = 0; j <= 10; j++)
v.push_back (i*j + num*foo(a,b));
}
// etc... for other cases
return v;
}

int main() {}


and this is the best solution I could come up with:



#include <iostream>
#include <vector>
#include <utility>

int foo (int a, int b) {return (a+1)*(b-1);}

struct Object {
int num;

std::vector<int> get(const Object*) const;

template <typename... Args>
std::vector<int> getHelper (int (Object::*)(int, int, Args...) const, Args...) const;

int sum (int x, int y) const {return x + y + num;}
int bar (int i, int j, int a, int b) const {return i*j + num * foo(a,b);}
};

template <typename... Args>
std::vector<int> Object::getHelper (int (Object::*f)(int, int, Args...) const, Args... args) const {
std::vector<int> v;
for (int i = 0; i < 3; i++)
for (int j = 0; j < 3; j++)
v.push_back ((this->*f)(i, j, args...));
return v;
}

std::vector<int> Object::get (const Object* o) const {
std::vector<int> v;
if (num < 5)
// return getHelper<> ([this](int i, int j)->int {return i + j + num;}); // Won't compile
return getHelper (&Object::sum);
else if (num < 10) {
const int a = o->num * (o->num - 1) * (o->num + 2);
const int b = o->num * (o->num - 3) * (o->num + 4);
// const auto bar = [this](int i, int j, int a, int b)->int {return i*j + num * foo(a,b);};
// return getHelper<int, int> ([this](int i, int j, int a, int b)->int {return i*j + num * foo(a,b);}, a, b); // Won't compile
return getHelper (&Object::bar, a, b);
}
return v;
}

int main() {
Object o{3}, p{6};
std::vector<int> v = o.get(&p);
for (int x : v) std::cout << x << ' ';
}


Output:



3 4 5 4 5 6 5 6 7


I really don't like the fact that I needed to added extra functions in Object to pass into the argument of Object::getHelper. I will be getting a lot of extra functions placed in Object as a result, whose usage will only be in Object::getHelper. But the lambda function I commented out won't compile. Anyone make this work, or think of a better method altogether?


Aucun commentaire:

Enregistrer un commentaire