[try Beta version]
Not logged in

 
Compiler picking the wrong overloaded function

Oct 5, 2020 at 11:57am
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 Oct 5, 2020 at 12:00pm
Oct 5, 2020 at 12:11pm
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.
Oct 5, 2020 at 12:29pm
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?
Oct 6, 2020 at 6:53pm
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 Oct 6, 2020 at 6:53pm
Topic archived. No new replies allowed.