I’m experimenting with std::remove_reference. For example, I can extract an element type an array but how do I get remove_reference to work with STL containers? For example, I want to return an iterator to an element of a vector using remove_reference below:
#include <iostream>
#include <vector>
#include <type_traits>
using std::vector;
using std::cout;
using std::endl;
using std::begin;
using std::end;
using std::remove_reference;
template<typename T>
auto my_end(T& c) -> typename remove_reference<decltype(&c[0])>::type
{
return end(c)-1; //compile error when myend<vector> is instantiated
}
int main()
{
int ia[] = {1,2,3,4,5,6,7,8,10};
vector<int> v(begin(ia), end(ia));
auto my_back1 = *my_end(ia);
cout << my_back1 << endl; //prints 10
auto my_back2 = *my_end(v);
cout << my_back2 << endl; //should print 10
}
The compiler error when my_end<vector> is instantiated is:
cannot convert from 'std::_Vector_iterator<_Myvec>' to 'int *'
What is the type returned by
std::vector<T>::operator[]? It is aT&. So, the result ofdecltype(&c[0])isT*.But what is the type of
end(c)-1? It is an iterator.If you want to return an iterator, use
decltype(end(c))or something similar.Note that if you just want a reference to the last element, you can just use (or wrap):
and if you want an iterator (for some reason), but don’t care about the direction:
which will also de-reference to the last entry.
Your
my_endis also unsafe if the container is empty … but of course I’m not sure how you plan to use it.