我正在看this talk from cppcon17并试图复制和理解所提出的错误。 但是,我无法复制/理解演讲中的错误#3(时间戳位于上面的链接中)。我写了这个最小的例子:
#include <iostream>
#include <map>
const std::string& getDefault(const std::map<int, std::string>& map, const int key, const std::string& defVal) {
auto pos = map.find(key);
return (pos != map.end() ? pos->second : defVal);
}
void printer(const std::string& str) {
std::cout << str << std::endl;
}
int main () {
std::map<int, std::string> myMap { {1, "dog"}, {2, "cat"}};
auto& retVal = getDefault(myMap, 3, "pizza");
printer(retVal);
return 0;
}
据我了解这个问题,“pizza”的临时默认值不应该通过引用返回,因为它应该被删除。 但为什么这个例子仍然有效呢?由于引用不再有效,我预计会出现错误。
编辑:我稍微修改了示例,以强调如果临时文件位于另一行,问题仍然会发生。
最佳答案
此代码,即std::cout << getDefault(myMap, 3, "pizza") << std::endl;
是有效的; temporary将在完整表达式之后被销毁,即在;
之后,返回的引用在传递给operator<<
的std::cout
并打印出来时仍然有效。
All temporary objects are destroyed as the last step in evaluating the full-expression that (lexically) contains the point where they were created,
编辑
您更新的代码具有未定义的行为。在;
之后,临时对象已被销毁,retVal
被悬空;对它的任何取消引用都会导致 UB。
关于c++ - 返回对临时对象的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65129361/