可重用性:以向量为参数的函数
reusability : function with vector as argument
下面是我经常遇到的那种代码:
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);
}
在使用 complexFunction()
函数之前,是否有一种优雅的方法来避免将 vector
的内容复制到另一个 vector
中?
我看到的另一种选择是为数据 MyData::a
和 MyData::b
创建两个临时函数,但这迫使我复制 complexFunction()
的代码。
C++11 中有哪些好的做法?
您可以传递 lambda 函数来获取复杂数据的字段。
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; });
可能是这样
#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;
}
下面是我经常遇到的那种代码:
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);
}
在使用 complexFunction()
函数之前,是否有一种优雅的方法来避免将 vector
的内容复制到另一个 vector
中?
我看到的另一种选择是为数据 MyData::a
和 MyData::b
创建两个临时函数,但这迫使我复制 complexFunction()
的代码。
C++11 中有哪些好的做法?
您可以传递 lambda 函数来获取复杂数据的字段。
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; });
可能是这样
#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;
}