为函数返回的右值引用赋值

Jon*_*201 9 c++ rvalue rvalue-reference c++11 c++14

#include <utility>
template <typename Container>
decltype(auto) index(Container &&arr, int n) {
    return std::forward<Container>(arr)[n];
}
Run Code Online (Sandbox Code Playgroud)

进行函数调用:

#include <vector>
index(std::vector {1, 2, 3, 4, 5}, 2) = 0;
Run Code Online (Sandbox Code Playgroud)

当函数调用完成时,对象std::vector {1, 2, 3, 4, 5}将被销毁,为释放的地址赋值会导致未定义的行为。但是上面的代码运行良好,valgrind 什么也没检测到。也许编译可以帮助我制作另一个不可见的变量,例如

auto &&invisible_value {index(std::vector {1, 2, 3, 4, 5}, 2)};
invisible_value = 9;
Run Code Online (Sandbox Code Playgroud)

如果我的猜测不正确,我想知道为什么为从函数返回的右值引用赋值是可行的,以及临时对象index(std::vector {1, 2, 3, 4, 5}, 2)何时会被销毁。

这个想法起源于?Effective Modern C++?,Item3:理解decltype

Pat*_*ker 7

你说“当函数调用完成时,对象向量 {1, 2, 3, 4, 5} 将被销毁”但这是不正确的。直到语句结束,即下一行代码,才删除为函数调用创建的临时文件。否则想象一下通过临时字符串的 c_str() 会破坏多少代码。

  • @Carsten _“所有临时对象都被销毁,作为评估(词汇上)包含它们创建点的完整表达式的最后一步”_ [来源](https://en.cppreference.com/w/cpp/语言/生命周期#Temporary_object_lifetime) (5认同)
  • @Carsten另外,您粘贴的引用实际上与我粘贴的引用一致,并且与您关于表达式以 return 语句结尾的说法相矛盾。创建临时变量的完整表达式是“index(vector {1, 2, 3, 4, 5}, 2) = 0;”,因此 _this_ 是保证临时变量存活的完整表达式。无论“index()”中发生什么都与这一点无关。 (2认同)