Search code examples
c++templatesduplication

how to avoid this duplicate code using templates in C++


I would like to eliminate duplicity of code in this problem:

class PopulationMember
{
public:
    vector<int> x_;
    vector<int> y_;
}

class Population
{
    vector<PopulationMember*> members_;

    void doComputationforX_1();  // uses the attribute x_ of all members_
    void doComputationforX_2();  
    void doComputationforX_3();

    void doComputationforY_1();  // exactly same as doComputationforX_1, but 
    void doComputationforY_2();  // uses the attribute y_ of all members_
    void doComputationforY_3();  

 EDIT: // there are also functions that use all the members_ simultaniously

    double standardDeviationInX(); // computes the standard deviation of all the x_'s
    double standardDeviationInY(); // computes the standard deviation of all the y_'s
}

The duplicity is causing me to have 6 methods instead of 3. The pairwise similarity is so striking, that I can get the implementation of doComputationforY_1 out of doComputationforX_1 by simply replacing the "x_" by "y_".

I thought about remaking the problem in this way:

class PopulationMember
{
public:
    vector<vector<int>> data_; // data[0] == x_ and data[1] == y_ 
} 

But it becomes less clear this way.

I know that a precompiler macro is a bad solution in general, but I do not see any other. My subconciousness keeps suggesting templates, but I just do not see how can I use them.


Solution

  • If you want to keep x_ and y_ separately in the same class PopulationMember then it's better to choose pass by value solution rather than template solution:

    Define the generic method as:

    void doComputationfor (vector<int> (PopulationMember::*member_));
                    // pointer to data  ^^^^^^^^^^^^^^^^^^^^^^^^^^
    

    Call it as:

    doComputationfor(&PopulationMember::x_);
    doComputationfor(&PopulationMember::y_);
    

    Remember that if your doComputationfor is large enough then, imposing template method would make code duplication.
    With the pointer to member method, you will avoid the code duplication with a little runtime penalty.