No C++11 is needed for this. Just have:
float & operator[](std::size_t i) { return data[i]; }
Now you can say v[2] = 5;
and all is well.
If you wanted, you could add a constant overload that doesn't use references and which can be used for reading the value.
float operator[](std::size_t i) const { return data[i]; }
The only time you might consider rvalue member function qualifiers is if you wanted to allow assigning to a temporary member:
vec4{}[2] = 5;
In that case, you still return a lvalue reference, but you must qualify the member function:
float & operator[](std::size_t i) && { return data[i]; }
// ^^^^