【发布时间】:2020-04-22 22:12:23
【问题描述】:
我在 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;
}
据我了解,RVO 应该启动并防止对返回的向量进行任何复制。但是,当我使用 GCC 时,一切正常,使用 msvc 时却不行,并且实际上复制了向量。有什么解释吗?谢谢!
编辑: 当我调试时,我确保函数内部和调用端的向量在内存中的引用是相同的。这对于 debian 测试上的 gcc 8.3 是正确的,而对于 Visual Studio 19.4 上的 msvc 则不是这样
【问题讨论】:
-
你是如何推断它被复制的?你确定它没有被移动吗?
-
您确实意识到您正在按值获取向量参数,并且实质上返回了一个悬空指针数组......同样,不相关:第一行最好写
std::vector<T*> out;。 可能更有利于优化。 -
具体说明您正在使用哪些工具链。在不同的平台上,GCC 和 Visual Studio 都有很多很多版本。
-
如果你最终没有得到悬空指针,那是优化的意外。如果您不通过引用将向量传递给函数,则确实存在未定义的行为。
-
否则,您的向量在返回时至少应移出函数(假设 C++11)。
标签: c++ gcc visual-c++ rvo