c++decltypetrailing-return-type

What is the meaning of function`->decltype()`


I've seen this one function I have no idea what's going on here:

template <typename Container>
auto MaxElement(Container &c,int num_of_el)->decltype(c[0]){
    int index=0;
    for(int i=1;i<num_of_el;i++)
        if(c[i]>c[index])
            index=i;
    return c[index];
}

This here is the main part of the program:

int main(){
    int a=7;
    vector<decltype(a)> v;
    v.push_back(a);
    a=10;
    v.push_back(5);
    cout<<v[0]<<" "<<v[1]<<endl;

    MaxElement(v,v.size())=10;
    cout<<v[0]<<" "<<v[1]<<endl;

    return 0;
}

I don't have a problem understanding how MaxElement function works, but rather with things like ->decltype(c[0])? What does that do? Also how can we do something like MaxElement(v,v.size())=10, what happens here?


Solution

  • ->decltype(c[0])? What does that do?

    In combination with auto as the return type, it declares the return type of the function to be of the same type as c[0], which is an int&.

    In this case, it means that the type of the function has the same type as a reference to an element in the Container.

    This is to help C++11 compilers which can't deduce this with just auto.

    A simplified example:

    This doesn't work in C++11:

    template<typename Container>
    auto foo(Container& c) {                       // auto is `int` in >= C++14 
        return c[0];
    }
    

    But this does:

    template<typename Container>
    auto foo(Container& c) -> decltype(c[0]) {     // auto is `int&`
        return c[0];
    }
    

    Also how can we do something like MaxElement(v,v.size())=10, what happens here?

    In a function returning a non-const reference to an object, you can assign to that object like any other.

    Note that auto (without the trailing decltype(C[0]) in C++14 and forward) will not return a reference to the returned object. It'll return it by-value - and then the assignment would not compile.