为什么这里不允许将矢量附加到另一个矢量?

时间:2014-02-12 16:18:57

标签: c++ vector

我使用方法(c ++)将一个向量追加到另一个向量:

a.insert(a.end(), b.begin(), b.end());

它有效,但是如果从成员函数中获取b,那么它就不再工作了,比如说

vector<point> const line::returnAVectorOfPoints() const
{
    vector<point> pts;
    // Do something
    return pts;
}

然后这次,当我尝试(类似这样的事)时

a.insert(a.end(), returnAVectorOfPoints().begin(), returnAVectorOfPoints().end());

我有一个segv。任何想法在这里出了什么问题?

5 个答案:

答案 0 :(得分:7)

您在line::returnAVectorOfPoints()中按值返回向量,因此这两个迭代器不兼容:

returnAVectorOfPoints().begin(), returnAVectorOfPoints().end()

他们指向两个不同的临时对象。

您可以将返回值存储在临时变量中:

auto v = returnAVectorOfPoints();
a.insert(a.end(), v.begin(), v.end());

另外,请注意,您不应返回const值。它会抑制移动语义,这可能会非常昂贵。

答案 1 :(得分:2)

这是因为你的:

line::returnAVectorOfPoints() 

每次将新实例作为临时值返回时,更改为:

vector<point> vec = returnAVectorOfPoints();
a.insert(a.end(), vec.begin(), vec.end());

答案 2 :(得分:2)

这是因为您引用了两个不同的,临时创建的向量。尝试

auto pts = returnAVectorOfPoints();
a.insert(a.end(), pts.begin(), pts.end());

答案 3 :(得分:1)

您还可以修改签名以返回参考。

它避免了不必要的矢量副本

vector<point>& const line::returnAVectorOfPoints() const

答案 4 :(得分:1)

正在堆栈上创建pts。当方法返回时,pts超出了范围。

尝试这样的事情:

vector<point> &line::returnAVectorOfPoints(vector<point> &pts) const
{    
    // Do something
    return pts;
}

你可以这样调用这个方法

vector<point> a;
returnAVectorOfPoints(a);

这样,矢量在方法的外部,因此它不会超出范围。

我相信它写不起来的原因是因为vector没有一个复制构造函数,允许编译器在它超出范围之前创建pts的中间副本。即使vector确实有一个复制构造函数,创建该中间副本也是一个昂贵的计算过程。

通过引用传递类可以避免不必要的副本。