2012-10-29 63 views
2

我正在试验std :: remove_reference。例如,我可以提取元素类型的数组,但是如何获取remove_reference以使用STL容器?例如,我要一个迭代器重新使用remove_reference下面的一个向量的元素:使用std :: remove_reference获取STL容器的元素迭代器

#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 *' 
+0

'decltype(C [0])'看起来不正确 –

+2

为什么不只是'typename的T :: iterator'?或者'decltype(c.begin())',如果你真的必须的话。 –

+1

@KerrekSB或'decltype(end(c)-1)'如果他真的必须。 – pmr

回答

6

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

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

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


请注意,如果你只是想最后一个元素的引用,你可以使用(或包裹):

ia.back(); 

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

ia.rbegin(); 

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

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

4

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

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

如果你想要的是返回一个迭代器,然后声明这样说:

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

但话又说回来,你想和remove_reference实验,吧...?

+0

我知道代码看起来没用(它是),但它只是一个'remove_reference'的玩具例子,如果我将一个迭代器传递到my_end()中,它看起来更有用。例如:'template auto my_end(T It) - > typename remove_reference :: type { return It-1; } int main() { int ia [] = {1,2,3,4,5,6,7,8,10}; vector v(begin(ia),end(ia)); auto my_back1 = my_end(end(ia)); cout << * my_back1 << endl; //打印10 auto my_back2 = my_end(end(v)); cout << * my_back2 << endl; //应该打印10 }' – hhbilly

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 
} 
+0

任何人都可以评论如何解决如何使用'remove_reference()'来推断返回类型吗? – hhbilly