Вторая перегрузка выбрана потому, что она лучше соответствует типам аргументов, когда Input
равно int
. В частности, учитывая аргументы (int, int)
, перегрузка (int, int)
лучше соответствует перегрузке (size_t, int const&)
. Обратите внимание, что если вы измените первый параметр первой перегрузки с size_t
на int
, он будет выбран вместо.
Если вы хотите отключить перегрузку шаблона функции, когда Input
является входным итераторомВы можете использовать SFINAE , используя std::enable_if
:
template <
typename InputIt,
typename = std::enable_if_t<
std::is_base_of_v<
std::input_iterator_tag,
typename std::iterator_traits<InputIt>::iterator_category>>>
vector(InputIt, InputIt)
{
}
При желании вы можете извлечь логику в черту типа.
template <typename T, typename = void>
struct is_input_iterator : std::false_type
{
};
template <typename T>
struct is_input_iterator<T, std::void_t<typename std::iterator_traits<T>::iterator_category>>
: std::is_base_of<
std::input_iterator_tag,
typename std::iterator_traits<T>::iterator_category>
{
};
template <typename T>
constexpr bool is_input_iterator_v = is_input_iterator<T>::value;
Тогда определение функции становится немного более читабельным.
template <
typename InputIt,
typename = std::enable_if_t<is_input_iterator_v<InputIt>>>
vector(InputIt, InputIt)
{
}