Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deduced Return Type

Tags:

c++

c++14

#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;
}

What's the difference between the return types of foo() and bar()?

std::forward<Container>(c) just keeps its "original" type. How does it affect the turn type? As it seems to me, when c is a rvalue reference, std::forward<Container>(c)[i] still returns a reference to the i-th element; when c is lvalue reference, std::forward<Container>(c)[i] still returns a reference to the i-th element.

I am sure I miss something.

like image 345
HCSF Avatar asked Jun 26 '19 09:06

HCSF


1 Answers

std::vector::operator[] doesn't have overload for rvalue this. so in your case, there are no changes.

but for class like:

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

it would make a difference.

like image 186
Jarod42 Avatar answered Sep 20 '22 02:09

Jarod42