4
나는 enable_if를 사용하는 법을 배워야합니다. 이를 위해 나는 enable_if를 사용하여 distance 함수를 다시 구현해야합니다. 나는 type_traits을 확인하지만 뭔가 특정 반복자 경우 확인을 위해 아무것도 찾을 수 없습니다 enable_if를 올바르게 사용하는 방법은 무엇입니까?
#include <iostream>
#include <vector>
#include <list>
#include <utility>
#include <type_traits>
template<class In>
typename std::enable_if<!std::is_random_acces_iterator<In>::value, std::iterator_traits<In>::difference_type>::type my_distance(In begin, In end, std::input_iterator_tag dummy){
typename std::iterator_traits<In>::difference_type n = 0;
while(begin!=end){
++begin; ++n;
}
std::cout << "STEPPING" << std::endl;
return n;
}
template<class Ran>
typename std::enable_if<std::is_random_acces_iterator<Ran>::value, std::iterator_traits<In>::difference_type>::type my_distance(Ran begin, Ran end, std::random_access_iterator_tag dummy){
std::cout << "RANDOM" << std::endl;
return end - begin;
}
template <class I> inline
typename std::iterator_traits<I>::difference_type my_distance_wrapper(I begin, I end){
typedef typename std::iterator_traits<I>::iterator_category cat;
return my_distance(begin, end, cat());
}
int main() {
std::vector<int> ve;
std::list<int> li;
for(int i = 0; i < 3; i++){
ve.push_back(i);
li.push_back(i);
}
std::cout << my_distance_wrapper(ve.begin(), ve.end()) << std::endl;
std::cout << my_distance_wrapper(li.begin(), li.end()) << std::endl;
return 0;
}
가 나는 비슷한
std::is_random_acces_iterator<In>::value
std::is_pod<In>::value
에 같은 일부 기능을 사용하여이 작업을 수행 할 수 있다고 생각 : 나는 이것을 시도했다. 뭔가 random_acces_iterator가 있는지 어떻게 확인하나요? 나는 함수 내에서 이것을 할 수 있다는 것을 알고있다 :
template<class T>
bool f(){
typedef typename std::iterator_traits<T>::iterator_category cat;
return std::random_access_iterator_tag == cat();
}
그럼 내 질문은 기본적으로 어떻게 함수 f를 템플릿에서 하는가? 그리고 enable_if를 사용할 수 없다는 것은 내 작업의 요구 사항입니다. 그리고 SFINAE가 함수 f를 그 템플릿에 넣을 수 있다면 다른 함수를 올바르게 버릴 것이라고 생각하는 것이 맞습니까?
template<typename iterator>
using is_random_access_iterator =
std::is_same<typename std::iterator_traits<iterator>::iterator_category,
std::random_access_iterator_tag>;
하고 여기에 다음
template<typename iterator>
std::enable_if_t<is_random_access_iterator<iterator>::value,
typename std::iterator_traits<iterator>::difference_type>
my_distance(iterator a, iterator b) { return a-b; }
template<typename iterator>
std::enable_if_t<!is_random_access_iterator<iterator>::value,
typename std::iterator_traits<iterator>::difference_type>
my_distance(iterator a, iterator b) { /* ... */ }
을 다음과 같이
해결책을 사용하려고하면 '예상 유형이 있습니다.'라는 메시지가 나타납니다. iterator_traits <_Iterator> :: iterator_category '' – Hakaishin
@Hakaishin 괜찮습니다. 테스트하지 않았습니다. 'typename'을 잊어 버렸습니다. – Walter
왜 그런지 모르지만 이전 의견을 수정할 수 없습니다. 그러나 어쨌든이 전체 메타 프로그래밍 작업은 단순히 프로그래밍 만하는 것 같지만이 내부에서는 가능합니다. 나는 잠재적 인 이익을보고 있지만 때로는 모든 것을 배우는 가치가 있고 실제로 얼마나 자주 사용되는지 스스로에게 묻습니다. – Hakaishin