可重用性:以向量为参数的函数

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::aMyData::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;
}