【问题标题】:Deduced Return Type推导返回类型
【发布时间】:2019-06-26 09:28:34
【问题描述】:
#include <iostream>
#include <vector>

template<typename Container, typename Index>
decltype(auto)
foo(Container&& c, Index i) {
    return std::forward<Container>(c)[i];
}

template<typename Container, typename Index>
decltype(auto)
bar(Container&& c, Index i) {
    return c[i];
}

int main() {
    std::vector<uint32_t> q{1, 3, 5};
    std::vector<uint32_t> r{2, 4, 6};

    std::cout << "lvalue" << std::endl;
    std::cout << foo(q, 1) << std::endl;
    std::cout << bar(q, 1) << std::endl;

    std::cout << "rvalue" << std::endl;
    std::cout << foo(std::move(q), 1) << std::endl;
    std::cout << bar(std::move(r), 1) << std::endl;
}

foo()bar()的返回类型有什么区别?

std::forward&lt;Container&gt;(c) 只是保持其“原始”类型。它如何影响转弯类型?在我看来,当c 是右值引用时,std::forward&lt;Container&gt;(c)[i] 仍然返回对第 i 个元素的引用;当c 是左值引用时,std::forward&lt;Container&gt;(c)[i] 仍然返回对第 i 个元素的引用。

我确定我错过了什么。

【问题讨论】:

  • 有谁知道如果foo 与临时值一起使用会发生什么?喜欢auto val = foo(std::vector&lt;int&gt;{3,2,1},1)。我的感觉是,这会产生对已删除值的引用,这将是未定义的行为。是吗?

标签: c++ c++14


【解决方案1】:

std::vector::operator[] 没有右值重载。所以在你的情况下,没有变化。

但是对于像这样的类:

template <typename T>
struct S
{
    T operator [](std::size_t) &&;
    T& operator [](std::size_t) &;
    // ...
};

这会有所作为。

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多