C ++ - 从函数返回向量

时间:2013-02-15 01:00:22

标签: c++ pointers vector

来自Java背景,我试图理解C ++中的指针/引用。我试图从函数返回一个向量。写作:

vector<char*> f(){
    vector<char*> vec;
    return vec;
}

会返回向量的副本,对吗?更好的方法是返回一个指向vector的指针,如下所示:

vector<char*>* f(){
    vector<char*>* vec = new vector<char*>;
    return vec;
}

我是正确的,还是完全错了?

3 个答案:

答案 0 :(得分:1)

在C ++ 03中,按值返回最有可能导致RVO(返回值优化),这将消除不必要的副本。在C ++ 11中,移动语义将处理副本。

那么,为什么首先按价值回报呢?因为它可以防止不必要的物体具有动态寿命。您的示例代码也不尊重您的函数用户可能想要使用的任何分配策略。

一般来说,返回一个容器即使在C ++ 11中也是一个坏主意:它将用户限制在该特定容器中,因为它不可能跨容器移动,只能复制。标准库使用OutputIteratorS解决了这个问题。您的算法最有可能写成:

template<typename OutputIterator>
OutputIterator f(OutputIterator o);

这样你就可以从容器中抽象出来并避开原来的问题。

答案 1 :(得分:0)

你错了,你不想在C ++中这样做。几乎每个C ++编译器都有所谓的命名返回值优化,它将(有效地)通过为堆栈上的返回值分配空间来移动而不是复制vec,然后基本构建“到位”。这消除了开销。

关于此的Wikipedia文章提供了合理的纲要。

答案 2 :(得分:0)

  

我是正确的,还是完全错了?

这是完全错误的,至少在C ++ 11中存在移动语义,并且只要您不需要创建返回值的别名 (这似乎不是你的情况,即使它是,可能需要使用智能指针而不是原始指针)。

按值返回向量现在可以。大多数情况下,即使在C ++ 98中,编译器也会忽略对复制构造函数的调用(以及C ++ 11中的移动构造函数)。这称为(Named) Return Value Optimization

在C ++ 11中,标准库的所有容器都支持移动构造函数,因此即使没有省略复制或移动,按值返回容器并不昂贵。