wpark
wpark

Reputation: 105

Calling wrong template function prototype problem in c++

I am currently making my custom vector container for understanding better the real STL containers. I am confront with the problem of "insert" function.

These are two prototypes of "insert" in my vector container.

// 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)

When I try to use insert function in main.cpp like below,

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

I intended to call first prototype but it calls second one which is for iterator params... Could you please explain me why it happens and how to solve it ?

Upvotes: 2

Views: 233

Answers (3)

rustyx
rustyx

Reputation: 85392

You need to use some SFINAE to restrict the InputIterator overload to iterator types.

Assuming your iterator adheres to iterator_traits and/or has a nested type like iterator_category, you can check for its presence via 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)

Upvotes: 3

Martin Morterol
Martin Morterol

Reputation: 2870

The line :

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

will deduce InputIterator to int and it will be a perfect match. Instead the first function will have to convert the int into size_type and value_type (probably not int)

You should use SFINAE to restrict the second for types which match InputIterator concept, so only the first one will be considered.

Upvotes: 1

3CxEZiVlQ
3CxEZiVlQ

Reputation: 38558

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

Upvotes: 0

Related Questions