C++ 使用容器时不同编译器上的RVO

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

我在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 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使用(命名)变量。