在C ++ 11中,要求编译器从返回的局部变量中隐式移动。而且,大多数编译器在许多情况下都可以执行复制省略并完全消除此举。结果,返回可以廉价移动的大对象不再需要特殊处理:
#include <vector> #include <iostream> // 如果编译器无法执行命名返回值优化(NRVO) // 并完全取消移动,则需要从v移到返回值。 std::vector<int> fillVector(int a, int b) { std::vector<int> v; v.reserve(b-a+1); for (int i = a; i <= b; i++) { v.push_back(i); } return v; // 隐式移动 } int main() { // 声明并填充向量 std::vector<int> vec = fillVector(1, 10); // 打印矢量图 for (auto value : vec) std::cout << value << " "; // this will print "1 2 3 4 5 6 7 8 9 10 " std::cout << std::endl; return 0; }
在C ++ 11之前,大多数编译器已经允许并实现了复制省略。但是,由于缺少移动语义,因此在遗留代码或必须使用未实现此优化功能的较早版本的编译器进行编译的代码中,您可以找到作为输出参数传递的向量,以防止不必要的复制:
#include <vector> #include <iostream> // 通过引用传递一个std :: vector void fillVectorFrom_By_Ref(int a, int b, std::vector<int> &v) { assert(v.empty()); v.reserve(b-a+1); for (int i = a; i <= b; i++) { v.push_back(i); } } int main() {// 声明向量 std::vector<int> vec; // 填充向量 fillVectorFrom_By_Ref(1, 10, vec); // 打印矢量图 for (std::vector<int>::const_iterator it = vec.begin(); it != vec.end(); ++it) std::cout << *it << " "; // this will print "1 2 3 4 5 6 7 8 9 10 " std::cout << std::endl; return 0; }