我使用方法(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。任何想法在这里出了什么问题?
答案 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确实有一个复制构造函数,创建该中间副本也是一个昂贵的计算过程。
通过引用传递类可以避免不必要的副本。