Выведенный тип возврата - PullRequest
7 голосов
/ 26 июня 2019
#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<Container>(c) просто сохраняет свой «оригинальный» тип.Как это влияет на тип поворота?Как мне кажется, когда c является rvalue ссылкой, std::forward<Container>(c)[i] по-прежнему возвращает ссылку на i-й элемент;когда c является ссылкой lvalue, std::forward<Container>(c)[i] по-прежнему возвращает ссылку на i-й элемент.

Я уверен, что что-то упустил.

1 Ответ

8 голосов
/ 26 июня 2019

std::vector::operator[] не имеет перегрузки для этого значения.поэтому в вашем случае изменений нет.

, но для класса, подобного:

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

, это будет иметь значение.

...