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 a T&. So, the result of decltype(&c[0]) is T*.
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):
ia.back();
and if you want an iterator (for some reason), but don't care about the direction:
ia.rbegin();
which will also de-reference to the last entry.
Your my_end is also unsafe if the container is empty ... but of course I'm not sure how you plan to use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With