关于在C++中返回容器:指针VS非指针

Kar*_*arl 1 c++ containers return function

我需要直截了当.使用下面的代码:

vector<unsigned long long int> getAllNumbersInString(string line){
    vector<unsigned long long int> v;   
    string word;
    stringstream stream(line);
    unsigned long long int num;

    while(getline(stream, word, ',')){
    num = atol(word.c_str());
    v.push_back(num);
    }

    return v;
}
Run Code Online (Sandbox Code Playgroud)

此示例代码只是将输入字符串转换为存储在vector中的一系列unsigned long long int.

在上面的这种情况下,如果我有另一个函数调用这个函数,并且我们看起来在向量中有大约100,000个元素,这是否意味着,当我们返回它时,将创建一个新的向量并且将创建与该向量相同的元素在函数中,然后函数中的原始向量将在返回时被消除?到目前为止我的理解是否正确?

通常,我会以这样的方式编写代码:所有函数在返回容器时都会返回指针,但是,程序设计方面,并且根据我的理解,我们应该总是返回指向容器的指针吗?

Jos*_*eld 8

std::vector将最有可能(如果你的编译器优化已打开)可以直接在函数的返回值构成.这称为复制/移动省略,是允许编译器进行的优化:

在具有类返回类型的函数的return语句中,当表达式是具有与函数返回类型相同的cv-unqualified类型的非易失性自动对象(函数或catch子句参数除外)的名称时,通过将自动对象直接构造到函数的返回值中,可以省略复制/移动操作

该引用取自C++ 11标准,但与C++ 03类似.重要的是要注意,复制/移动省略根本不必发生 - 这完全取决于编译器.大多数现代编译器都会毫无问题地处理您的示例.

如果没有出现elision,C++ 11仍将为您提供比C++ 03更多的优势:

  • 在C++ 03中,没有复制省略,返回std::vector类似这样的内容就像你说的那样,将所有元素复制到返回的对象然后销毁本地std::vector.

  • 在C++ 11中,std::vector移出函数.移动允许返回std::vector窃取的内容std::vector是将被摧毁.复制内容的效率要高得多.

    您可能已经预料到该对象将被复制,因为它是一个左值,但是有一个特殊规则使得像这样的副本首先被视为移动:

    当满足复制操作的省略标准并且要通过左值指定要复制的对象时,首先执行用于选择复制的构造函数的重载决策,就好像该对象由右值指定一样.

至于你是否应该返回指向容器的指针:答案几乎肯定是否定的.你不应该传递指针,除非它是完全必要的,并且在必要时,你最好使用智能指针.正如我们所见,在你的情况下它根本没有必要,因为按价值传递它几乎没有开销.