如何通过引用返回一个向量,隐含地期望一个空向量作为输入?

Posted

技术标签:

【中文标题】如何通过引用返回一个向量,隐含地期望一个空向量作为输入?【英文标题】:How to return a vector by reference implicitly expecting an empty vector as input? 【发布时间】:2016-07-12 07:46:29 【问题描述】:

假设我有一个点向量,并希望在一个函数调用中将其分成两个其他向量。我将如何最好地返回这些向量。 我目前的方法是通过引用将两个所需的输出向量都提供给函数。

void separatePoints(const vector<Point> &P, vector<Point> &P_1, vector<Point> &P_2)
    
   for (size_t i = 0; i < P.size(); P++)
   
     if (P[i].x < 100 && P[i].y < 100)
       P_1.push_back(P[i]);
     else 
       P_2.push_back(P[i]);
   


vector<Point> P;
//.... this vector should be filled and contain some points
vector<Point> P_1, P_2; //not initialised
separatePoints(P, P_1, P_2);

当我执行上述操作时,如果输出向量 P_1P_2 为空,它会正常工作并且符合预期,否则点将附加到向量中。如果需要这样就可以了,但是如果不需要怎么办?

当然,我可以在函数调用中创建两个新向量,并将这些向量分配给函数末尾的P_1P_2。但这是一个好方法还是我目前缺少一些更好的方法?

void separatePoints(const vector<Point> &P, vector<Point> &P_1, vector<Point> &P_2)

   vector<Point> P_1_temp, P_2_temp;
   for (size_t i = 0; i < P.size(); P++)
   
     if (P[i].x < 100 && P[i].y < 100)
       P_1_temp.push_back(P[i]);
     else 
       P_2_temp.push_back(P[i]);
   
   P_1 = P_1_temp;
   P_2 = P_2_temp;

【问题讨论】:

P_1.resize(0); P_2.resize(0); 怎么样? 你可以简单地P_1.clear(); P_2.clear(); 你可以先清除它们,或者在最后移动2个局部向量。 【参考方案1】:

如果要返回结果,我建议使用返回值而不是引用或指针参数。它使代码更容易理解:

std::pair<std::vector<Point>, std::vector<Point>> separatePoints(const std::vector<Point> &P)

   std::pair<std::vector<Point>, std::vector<Point>> vectors;
   for (size_t i = 0; i < P.size(); P++)
   
       if (P.x[i] < 100 && P.y[i] < 100)
           vectors.first.push_back(P[i]);
       else 
           vectors.second.push_back(P[i]);
   
   return vectors;

如果您不喜欢 std::pair 声明的嵌套模板语法,请定义您自己的结构体

struct PointVectorPair 
    std::vector<Point> v1;
    std::vector<Point> v2;

【讨论】:

这不会创建向量的副本吗?我同意可读性,但它在计算方面也很有效吗? @Phann:你的意思是当这对被退回时?可能不会,大多数编译器在这种情况下都会对返回值进行优化以避免复制。【参考方案2】:

您可以将空向量对象作为非常量引用传递,或者将它们返回为std::pair&lt;std::vector&lt;&gt;,std::vector&lt;&gt;&gt;,或者将它们返回为std::tuple

std::pair:http://www.cplusplus.com/reference/utility/pair/

std::tuple:http://en.cppreference.com/w/cpp/utility/tuple

【讨论】:

以上是关于如何通过引用返回一个向量,隐含地期望一个空向量作为输入?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中通过引用返回向量

通过引用返回通过引用传递的向量的实用程序

将向量的引用作为参数传递

如何从函数返回向量引用?

空身体的重载运算符神奇地工作

将继承的类对象的向量传递给期望基类向量的函数