【问题标题】:reusability : function with vector as argument可重用性:以向量为参数的函数
【发布时间】:2021-07-02 14:58:13
【问题描述】:

这是我经常使用的那种代码:

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 中有哪些好的实践?

【问题讨论】:

  • 我无法清楚理解您的意思,但如果您询问有关复制矢量的问题,this 可以帮助您

标签: c++ vector reusability


【解决方案1】:

您可以传递一个 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; });
 

【讨论】:

  • 我可能会选择使用指向成员的指针而不是 lambda,例如:std::vector&lt;double&gt; complexFunction(const std::vector&lt;MyData&gt;&amp; vIn, double MyData::*member) { ... use (vIn[i].*member) as needed ... } ... auto vOut_a = complexFunction(vIn, &amp;MyData::a); auto vOut_b = complexFunction(vIn, &amp;MyData::b);
  • 如果不需要成员的转换就完美了!
【解决方案2】:

可能是这样

#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;
}

【讨论】:

    猜你喜欢
    • 2023-03-28
    • 2018-10-02
    • 2020-06-03
    • 1970-01-01
    • 2019-10-10
    • 2014-09-03
    • 1970-01-01
    • 2013-02-22
    相关资源
    最近更新 更多