C++ 使用容器时不同编译器上的RVO
我在c++17上有以下代码C++ 使用容器时不同编译器上的RVO,c++,gcc,visual-c++,rvo,C++,Gcc,Visual C++,Rvo,我在c++17上有以下代码 template<typename T> std::vector<T*> getPointerVector(std::vector<T> base) { auto out = std::vector<T*>(); for (auto& t : base) { out.push_back(&t); } return out; } 模板 std::vector getPointe
template<typename T>
std::vector<T*> getPointerVector(std::vector<T> base) {
auto out = std::vector<T*>();
for (auto& t : base) {
out.push_back(&t);
}
return out;
}
模板
std::vector getPointerVector(std::vector base){
自动输出=标准::向量();
用于(自动和测试:基础){
向外。向后推(&t);
}
返回;
}
据我所知,RVO应该介入并防止对返回向量的任何复制。然而,当我使用GCC时,它一切正常,而使用msvc时,它不正常,而且向量实际上是复制的。有什么解释吗?谢谢
编辑:
当我调试时,我确保内存中的引用对于函数内部和调用端的向量是相同的。这对于debian测试上的gcc 8.3是正确的,而对于VisualStudio19.4上的msvc则不正确。显然,您的VisualStudio版本不能做到这一点 或者 当我调试时,我确保内存中的引用对于函数内部和调用端的向量是相同的。这对于debian测试上的gcc 8.3是正确的,而对于VisualStudio19.4上的msvc则不正确 如果您正在调试,那么很可能您正在进行调试构建,而对于调试构建,优化通常不那么激烈。所以很可能是你把它关掉了 它至少会移动向量,就是这样
顺便说一下,您返回的向量的每个元素都是一个悬空指针。你的意思是参考
base
?另外,out.reserve(base.size())
调用也不会有什么坏处。您是如何推断它被复制的?你确定它没有被移动吗?你知道你正在按值获取向量参数,并返回一个悬空指针数组。。。另外,不相关的:第一行写得更好std::vector out代码>。可能更有利于优化。具体说明您使用的工具链。GCC和visualstudio在不同的平台上都有很多不同的版本,如果你没有得到悬空的指针,那只是一个优化的意外。如果不通过引用将向量传递到函数中,则存在未定义的行为。否则,在返回向量时,至少应将向量移出函数(假设为C++11)。在C++17中,NRVO不是强制要求的。和OP使用(命名)变量。