2

我正在试验 std::remove_reference。例如,我可以将元素类型提取为数组,但如何让 remove_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 *'  
4

3 回答 3

6

返回的类型是std::vector<T>::operator[]什么?它是一个T&. 所以,结果decltype(&c[0])T*

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

如果你想返回一个迭代器,使用decltype(end(c))或类似的东西。


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

ia.back();

如果你想要一个迭代器(出于某种原因),但不关心方向

ia.rbegin();

这也将取消对最后一个条目的引用。

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

于 2012-10-29T15:33:42.367 回答
4

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

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

如果你想要的只是返回一个迭代器,那么像这样声明它:

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

但是话又说回来,您想尝试一下remove_reference,对吧...?

于 2012-10-29T15:32:35.807 回答
0

谢谢你们的帮助。代码在我下面的评论中看起来很蹩脚,所以又来了。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
}
于 2012-10-29T18:28:35.627 回答