emba
emba

Reputation: 21

reusability : function with vector as argument

Here is the kind of code I often have:

struct MyData
{
public:
  double a;
  double b;
};

std::vector<double> complexFunction(const std::vector<double>& vIn)
{
  std::vector<double> vOut;
  // complex calculations on the vector vIn to make vOut
  return vOut;
}

int main(int argc, char **argv)
{
  std::vector<MyData> myVector;
  // Fill myVector...

  std::vector<double> vIn_a;
  vIn_a.resize(myVector.size());
  std::vector<double> vIn_b;
  vIn_b.resize(myVector.size());
  // I would like to avoid that
  for(size_t i=0; i < myVector.size(); ++i)
  {
    vIn_a[i] = myVector[i].a;
    vIn_b[i] = myVector[i].b;
  }

  // Now I can use complexFunction
  std::vector<double> vOut_a = complexFunction(vIn_a);
  std::vector<double> vOut_b = complexFunction(vIn_b);
  
  // A bad alternative solution...
  std::vector<double> vOut_a = complexFunction_specialForMyData_a(myVector);
  std::vector<double> vOut_b = complexFunction_specialForMyData_b(myVector);
}

Is there an elegant way to avoid copying the content of a vector into another vector before using the complexFunction() function?

The other alternative, that I see, is to create two adhoc functions for the data MyData::a and MyData::b, but this forces me to duplicate the code of complexFunction().

What are some good practices in C++11?

Upvotes: 0

Views: 63

Answers (2)

Evgen Buiko
Evgen Buiko

Reputation: 27

Maybe like this

#include <iostream>
#include <vector>
#include <functional>
#include <algorithm>

struct MyData
{
public:
  double a;
  double b;
};

// I think in this problem it would be more elegant to create local copy of needed members
std::vector<double> complexFunction( const std::vector<MyData>& vIn, double MyData::* member )
{
  auto member_access = std::mem_fn( member );
  std::vector<double> vInTemp;
  std::transform( vIn.begin(), vIn.end(), 
                  std::back_inserter( vInTemp ), 
                  [member_access]( const MyData& val ) 
                  { return member_access( val ); } );
  std::vector<double> vOut;

  // complex calculations on the vector vInTemp to make vOut
  return vOut;
}

int main( int argc, char** argv )
{
  std::vector<MyData> myVector = { { 1.0, 2.0 }, { 3.0, 4.0 } };
 
  std::vector<double> vOut_a = complexFunction( myVector, &MyData::a );
  std::vector<double> vOut_b = complexFunction( myVector, &MyData::b );

  return 0;
}

Upvotes: 1

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38783

You can pass a lambda function for getting a field of a complex data.

std::vector<double> complexFunction(const std::vector<MyData>& vIn, double (*get)(const MyData&))
{
 std::vector<double> vOut;
 // complex calculations on get(vIn[i]) to make vOut
 return vOut;
}
// Usage
std::vector<double> vOut_a = complexFunction(vIn, [](const MyData& d){ return d.a; });
std::vector<double> vOut_b = complexFunction(vIn, [](const MyData& d){ return d.b; });
 

Upvotes: 2

Related Questions