Вызов неправильного шаблона функции проблема прототипа в C ++ - PullRequest
1 голос
/ 01 мая 2020

В настоящее время я делаю свой собственный векторный контейнер для лучшего понимания реальных контейнеров STL. Я сталкиваюсь с проблемой «вставить» функцию.

Это два прототипа «вставки» в моем векторном контейнере.

// 1
template <typename T, typename Alloc>
void vector<T, Alloc>::insert(iterator position, size_type n, const value_type &val)

// 2
template <typename T, typename Alloc>
template <class InputIterator>
void vector<T, Alloc>::insert(iterator position, InputIterator first, InputIterator last)

Когда я пытаюсь использовать функцию вставки в main. cpp, как показано ниже,

int main() {
    ft::vector<int> my;
    my.insert(my.begin(), 5, 6); <-- it calls second proto.
    return (0);
}

Я намеревался вызвать первый прототип, но он вызывает второй, предназначенный для параметров итератора ... Не могли бы вы объяснить, почему это происходит и как его решить?

Ответы [ 3 ]

1 голос
/ 01 мая 2020

Вам нужно использовать некоторую SFINAE, чтобы ограничить перегрузку InputIterator типами итераторов.

Если ваш итератор придерживается iterator_traits и / или имеет вложенный тип, такой как iterator_category, вы можете проверить его присутствие через SFINAE:

template <class Iter>
using iter_cat_t = typename iterator_traits<Iter>::iterator_category;

template <class T, class = void>
constexpr bool is_iterator_v = false;

template <class T>
constexpr bool is_iterator_v<T, std::void_t<iter_cat_t<T>>> = true;

template <typename T, typename Alloc>
template <class InputIterator, std::enable_if_t<is_iterator_v<InputIterator>, int> = 0>
void vector<T, Alloc>::insert(iterator position, InputIterator first, InputIterator last)
0 голосов
/ 01 мая 2020
int main() {
    ft::vector<int> my;
    my.insert(my.begin(), 5u, 6); <-- it calls the first prototype.
    return (0);
}
0 голосов
/ 01 мая 2020

Строка:

my.insert(my.begin(), 5, 6); <-- it calls second proto.

выведет InputIterator к int, и это будет идеальное совпадение. Вместо этого первая функция должна будет преобразовать int в size_type и value_type (вероятно, не int)

. Вы должны использовать SFINAE, чтобы ограничить вторую для типов, которые соответствуют концепции InputIterator, поэтому будет рассматриваться только первый.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...