c++ - C++ 容器的 decltype、通用引用和转发

标签 c++ templates pass-by-reference decltype forwarding-reference

我正在阅读 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 for typeid of forwared for which I am expecting int &.

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/

相关文章:

c++ - 在模板类中通过引用传递

c++ - 使用 for 循环绘制边框

c++ - 赋值运算符的参数类型(引用或值?)

javascript - 在 Javascript 中通过引用传递字符串

c++ - 如何在C++中使用关键字delete删除特定的模板特化

java - 快速访问嵌套集合

c++ - 实现 parallel_for_each 函数

c++ - 使用 MATLAB 和 OpenCV 对图像求和的效率

c++ - 如何在 C++ 中导出具有返回类型 std::map 的函数

c++ - 多个 TCP 连接与单个连接