我正在阅读 Scott Meyers 撰写的有关 decltype
和 rvalue references in effective modern C++ 的书。我有以下代码
template <typename container, typename index>
decltype(auto) authAndAccess(container&& c, index i) {
std::cout << "auth and Access c type: " << typeid(c[i]).name() << std::endl;
std::cout << "auth and Access c type expecting reference: " << typeid(std::forward<container>(c)[i]).name() << std::endl;
return std::forward<container>(c)[i];
}
deque<int> makeStringDeque() {
deque<int> dqContainer = { 1,2,3,4,5 };
return dqContainer;
}
现在在主要功能中我有以下内容
deque<int> dqContainer = { 1,2,3,4,5 };
std::cout << "Value returned by container: " << authAndAccess(dqContainer, 4) << std::endl;
authAndAccess(deque<int>{1, 2, 3, 4, 5}, 4) = 10;
std::cout << "Value returned by container and 5th element after copying: " << dqContainer[4] << endl;
我的问题是 authAndAccess
函数采用右值参数,因此容器是临时的,返回的对象是临时引用元素。但是为什么输出显示为 int
for typeid
forwared 我期待 int &
。我确实理解 typeid 的名称函数不准确,但为什么在我们返回临时元素引用时它没有崩溃。
最佳答案
My question is
authAndAccess
function takes rvalue argument so container is temporary and return is object is temporary reference element.
authAndAccess
采用 Scott 所谓的通用引用,现在称为转发引用,因此它可以接受左值和右值参数。当你传递一个左值时,你得到一个左值引用,当你传递一个右值时,你得到一个右值引用。 std::forward<container>
做同样的事情。如果container
是左值,你得到一个左值,对于右值,你得到一个右值。
这意味着 authAndAccess(dqContainer, 4)
很好,因为您要返回对 dqContainer
中对象的引用仍然存在。在 authAndAccess(makeStringDeque(), 4)
你会认为自 makeStringDeque()
以来你有未定义的行为是临时的,您正在返回对它的引用,但由于您不保留它,所以没有 UB,因为该引用在完整表达式结束之前一直有效。
But why output is shown as
int
fortypeid
of forwared for which I am expectingint &
.
typeid
不会告诉你是否有引用。你可以在这个最小的例子中看到这一点
int main(int argc, char* argv[])
{
int a = 5;
int & b = a;
std::cout << typeid(b).name();
}
输出i
.如果您想获取类型,可以使用已声明但未定义的类模板并将类型赋予它,您将收到一条错误消息,告诉您实际类型是什么。如果我们把上面的代码改成
template<typename T>
struct type;
int main(int argc, char* argv[])
{
int a = 5;
int & b = a;
type<decltype(b)>{};
}
我们会得到类似这样的错误
main.cpp:14:5: error: implicit instantiation of undefined template 'type<int &>'
type<decltype(b)>{};
如您所见,它将类型推断为 int &
.如果我们在您的代码中这样做,它也会给出 int &
因为这是 c[i]
的返回类型.
关于c++ - C++ 容器的 decltype、通用引用和转发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55495964/