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

using std::remove_reference to get an element iterator of STL container

本文关键字:元素 迭代器 STL 获取 std remove reference 使用      更新时间:2023-10-16

我正在尝试std :: remove_reference。例如,我可以提取一个元素类型的数组,但是如何获得删除_Reference以与STL容器一起使用?例如,我想使用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
}

实例化my_end<vector>时的编译器错误为:

cannot convert from 'std::_Vector_iterator<_Myvec>' to 'int *'  

std::vector<T>::operator[]返回的类型是什么?这是T&。因此,decltype(&c[0])的结果是T*

但是end(c)-1的类型是什么?它是一个迭代器。

如果要返回迭代器,请使用decltype(end(c))或类似的东西。


请注意,如果您只想引用最后一个元素,则可以使用(或包装):

ia.back();

如果您想要迭代器(出于某种原因),但不在乎方向

ia.rbegin();

它也将推迟到最后一个条目。

如果容器为空,您的my_end也不安全...但是我当然不确定您打算如何使用它。

remove_reference的目的是什么?std::vector<T>::end()产生迭代器,而&c[0]产生指向元素的指针。

定义您期望的my_end()返回的内容,然后我们可以帮助您解决问题。

如果您想要的只是返回迭代器,请这样声明:

auto my_end(T& c) -> decltype(begin(c)) { }

但是,您想尝试一下remove_reference,对...?

感谢您的帮助。该代码在下面的评论中看起来很la脚,因此又来了。这次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 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
}