Reputation: 21
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
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
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