2012-10-29 3 views
2

표준 : : remove_reference를 실험하고 있습니다. 예를 들어 배열에 요소 유형을 추출 할 수 있지만 STL 컨테이너에서 작동하도록 remove_reference를 얻는 방법은 무엇입니까? 예를 들어, 나는 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

왜 그냥'유형 이름의 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 유형은 무엇입니까? iterator입니다.

반복자를 반환하려면 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()에 반복자를 전달하면 더 유용 해 보인다. 예 :'템플릿 자동 my_end (T It) -> typename remove_reference :: 유형 { return It-1; } int main() { int ia [] = {1,2,3,4,5,6,7,8,10}; 벡터 v (시작 (ia), 끝 (ia)); 자동 my_back1 = my_end (끝 (ia)); cout << * my_back1 << endl; // 인쇄 10 자동 my_back2 = my_end (끝 (v)); cout << * my_back2 << endl; // should should print 1 }' – 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

관련 문제