Compiler picking the wrong overloaded function

I am trying to implement std::list.

Here is the code stripped to only the part that is causing.
Stripped to make reading better to be able to analyze the problem.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>

using namespace std;

template <typename T>
class List
{
    //SFINAE
    template <typename Iter>
    using required_input_iterator = std::enable_if<std::is_base_of_v<std::input_iterator_tag,
          typename std::iterator_traits<Iter>::iterator_category >>;

public:
    using reference =                  T&;
    using const_reference =            const T&;
    using size_type =                  std::size_t;

    class const_iterator ;

    class iterator : public std::input_iterator_tag
    {

    };

    class const_iterator
    {

    };

    List() = default;
    List(std::initializer_list<T> i_list);

    // iterators
    const_iterator end() const noexcept {};
    iterator end() noexcept {};
    const_iterator  cend() const {};

    template<typename InputIterator>//, typename = required_input_iterator<InputIterator>>
    iterator insert(const_iterator pos, InputIterator first, InputIterator last);

};

template <typename T>
List<T>::List(std::initializer_list<T> i_list)
{
    insert(end(), i_list.begin(), i_list.end());
}


template<typename T>
template<typename InputIterator>
typename List<T>::iterator List<T>::insert(const_iterator pos, InputIterator first, InputIterator last)
{
    //
}

int main()
{
   List<int> ll({12, 7, 34, 5});

}


In the constructor the function insert is called however the compile throws this error:

error: no matching function for call to 'List<int>::insert(List<int>::iterator, std::initializer_list<int>::const_iterator, std::initializer_list<int>::const_iterator)'|

As it shows in the error the compiler is picking the List<int>::iterator version of end() when there is a perfect List<int>::const_iterator version.

If comment out
// iterator end() noexcept {};
The code works fine.

I have no idea how to fix this error.
I think the compiler should pick the right function but it doesn't.

Why this happens and how would it be fixed?
Last edited on
The compiler will pick the non const version of the end() function.

One way would be to use cend(). Another: make your const_iterator accept iterator.

Since insert(...) returns iterator it would make sense to pass iterator as well.
Simply, given a choice the non-const version is picked when the object is non-const and the const version is picked if the object is const.

What happens if you make ll const in your example?
One way would be to use cend().
I can do that, but the client code would not be able to insert an element at the end of the List because the same error I am facing right now will be thrown

1
2
3
4
5
6
...

List<int> list;
list.insert(list.end(), 33); // error would be thrown here

...


Another: make your const_iterator accept iterator.

Thanks, doing that solved my problem

I added this to my const_iterator class:

1
2
3
class const_iterator {
  const_iterator (const iterator& x) : node(x.node) {}
};
Last edited on
Topic archived. No new replies allowed.