简体   繁体   English

使用std :: remove_reference来获取STL容器的元素迭代器

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM