[英]using std::remove_reference to get an element iterator of STL container
I'm experimenting with std::remove_reference. 我正在尝试使用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? 例如,我可以提取元素类型数组但是如何使用remove_reference来处理STL容器? For example, I want to return an iterator to an element of a vector using remove_reference below: 例如,我想使用下面的remove_reference将迭代器返回到向量的元素:
#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: my_end<vector>
实例化时的编译器错误是:
cannot convert from 'std::_Vector_iterator<_Myvec>' to 'int *'
What is the type returned by std::vector<T>::operator[]
? std::vector<T>::operator[]
返回的类型是什么? It is a T&
. 这是一个T&
。 So, the result of decltype(&c[0])
is T*
. 因此, decltype(&c[0])
是T*
。
But what is the type of end(c)-1
? 但是什么是end(c)-1
的类型? It is an iterator. 它是一个迭代器。
If you want to return an iterator, use decltype(end(c))
or something similar. 如果要返回迭代器,请使用decltype(end(c))
或类似的东西。
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. 如果容器是空的,你的my_end
也不安全......但当然我不确定你打算如何使用它。
What's the purpose of remove_reference
here? remove_reference
的目的是remove_reference
? std::vector<T>::end()
yields an iterator, whereas &c[0]
yields a pointer to an element. std::vector<T>::end()
产生一个迭代器,而&c[0]
产生一个指向元素的指针。
Define what you are expecting my_end()
to return, and then we can help you solve the problem. 定义您期望my_end()
返回的内容,然后我们可以帮助您解决问题。
If all you want is to return an iterator, then declare it like this: 如果你想要的只是返回一个迭代器,那么声明它是这样的:
auto my_end(T& c) -> decltype(begin(c)) { }
But then again, you would like to experiment with remove_reference
, right...? 但remove_reference
回来,你想remove_reference
,对吧......?
Thanks for your help folks. 谢谢你们的帮助。 The code looks lame inline in my comment below so here it is again. 代码在下面的评论中看起来很蹩脚,所以这里又是。 This time remove_reference
is useful to deduce the return type if for example I need to pass an iterator. 这次remove_reference
对于推断返回类型很有用,例如我需要传递一个迭代器。 (Okay so its not exactly that useful....) (好吧所以它不是那么有用....)
#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 It) -> typename remove_reference<decltype(It)>::type
{
return It-1;
}
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(end(ia));
cout << *my_back1 << endl; //prints 10
auto my_back2 = my_end(end(v));
cout << *my_back2 << endl; //should print 10
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.