基于函数返回的stl容器构造效率

wus*_*978 4 c++ rvalue-reference move-semantics return-value-optimization c++11

我有一个返回stl容器的工厂函数:

const std::vector<int> f(...) {
    std::vector<int> retval;
    return retval;
}
Run Code Online (Sandbox Code Playgroud)

我想可以定义一个stl实例如下(没有错误):

const std::vector<int> stl_instance(f(...));
Run Code Online (Sandbox Code Playgroud)

但这样做有效吗?

是否将临时stl对象直接分配给stl_instance

Tem*_*Rex 5

返回const rvalue是C++ 11中的反模式.首先考虑返回非const rvalues:

std::vector<int> f(int n) 
{ 
    return std::vector<int>(n); 
}

int main() 
{ 
    std::vector<int> v; 
    v = f(3); 
} 
Run Code Online (Sandbox Code Playgroud)

在C++ 98/03中,此代码将至少进入堆两次:

  1. 在f内创建向量(如果RVO适用)
  2. 从f的回归分配给v.

如果您的编译器不应用RVO,则会获得3个堆分配.

在C++ 11中,您只获得1个堆分配:在其中创建向量f.无论RVO如何,都会发生这种情况.原因是所有STL容器都有移动构造函数和移动具有签名的赋值运算符

vector( vector&& other );
vector& operator=( vector&& other );
Run Code Online (Sandbox Code Playgroud)

rvalue引用&&将资源从创建函数内部直接移动到目标.但是,您的代码具有签名

const std::vector<int> f(int n) 
{ 
    return std::vector<int>(n); 
}
Run Code Online (Sandbox Code Playgroud)

将禁用移动语义,因为T &&(即移动构造函数和赋值运算符的参数)不会绑定到const rvalue参数(即函数的返回值).这有效地使您的代码在C++ 98/03下运行(即具有2或3个堆分配).