지금 과부하는 제한하지 않았기 때문에 모호합니다. 첫 번째 컴파일러가 반복자에 사용되어서는 안된다는 것을 컴파일러가 어떻게 알았습니까?
대답은 간단합니다. 다행히 표준은 std::iterator_traits
을 정의하며 전달 된 반복자 유형에 대한 모든 종류의 정보를 쿼리 할 수 있습니다 (반복자 인 한).
여기서 마지막 점은 키입니다. std::iterator_tags<T>
에 중첩 된 typedef iterator_category
이없는 경우 T
은 반복기가 아닙니다. 따라서 member detection using void_t
을 사용하여 지정된 유형이 반복자인지 확인하는 사용자 정의 특성을 정의 할 수 있습니다. 코드에서
, 그것은 다음과 같습니다
여기
// C++17 void_t
template <typename...>
using void_t = void;
template <typename T, typename = void>
struct is_iterator : std::false_type {
};
template <typename T>
struct is_iterator<T, void_t<typename std::iterator_traits<T>::iterator_category>> : std::true_type {
};
template <typename T>
constexpr auto is_iterator_v = is_iterator<T>::value;
가 나는 또한 편의를 위해 constexpr 변수 is_iterator_v
을 정의했다.
std::enable_if
과 함께이 특성을 사용하여 T
이 반복자인지 여부에 따라 이전에 모호한 두 가지 오버로드 중 하나를 선택적으로 비활성화 할 수 있습니다. 그렇게하려면 템플릿 선언 template <typename T>
을 각각 template <typename T, std::enable_if_t<is_iterator_v<T>, int> = 0>
및 template <typename T, std::enable_if<!is_iterator_v<T>, int> = 0>
으로 바꿉니다.
함께 최선을 다하는, 코드는 다음과 유사합니다 :
// C++17 void_t
template <typename...>
using void_t = void;
template <typename T, typename = void>
struct is_iterator : std::false_type {
};
template <typename T>
struct is_iterator<T, void_t<typename std::iterator_traits<T>::iterator_category>> : std::true_type {
};
template <typename T>
constexpr auto is_iterator_v = is_iterator<T>::value;
template<typename T, std::enable_if_t<!is_iterator_v<T>, int> = 0>
constexpr T maximum(T a, T b)
{
return (a > b) ? a : b;
}
template<typename Iter, std::enable_if_t<is_iterator_v<Iter>, int> = 0>
constexpr Iter maximum(Iter begin, Iter end)
{
if(begin == end) {
return end;
}
auto max = begin;
for (; begin != end; ++begin) {
if(*begin > *max) {
max = begin;
}
}
return max;
}
당신은 또한 wandbox에 작업 예를 찾을 수 있습니다.
예, 가능합니다. 너 해봤 어? 어디서 곤경에 빠졌습니까? – aschepler
함수 호출이 같은 이름의 함수 호출을 방해하지 않는 한 오버로드 문제가 있어서는 안됩니다 –
'int max (const int * p);'와 같은 함수를 구현할 수 없습니다 얼마나 많은 int가'p '를 가리키는 지 알 수 없으므로,'int max (const int * begin, const int * end);와 같은 것을 원할 것이다. –