[try Beta version]
Not logged in

 
Help Needed in completing STL-like list class

Dec 6, 2017 at 9:06pm
I have this code here in the following Gist that implements an STL-like list class: https://gist.github.com/DragonOsman/87a1e9fba06d49cab9b5b556c7dd31eb . I need to know how to complete it.

My list constructor that takes a "count" as the parameter isn't being called, so I need help on that as well. But I also need help on erase and insert functions that take a const_iterator parameter instead of a normal iterator parameter. I saw that the standard library has overloads of the erase and insert functions that take a const_iterator and return an iterator. When I try that on VS, I see "<error_type>" as the return type of the function when I try to call it. So I don't understand what to do for that.
Dec 7, 2017 at 9:59am
I need to know how to complete it
What do you mean by 'complete'. What is missing?

My list constructor that takes a "count" as the parameter isn't being called
What makes you think so?

I saw that the standard library has overloads of the erase and insert functions that take a const_iterator and return an iterator
Since both iterator type have one member Link<Elem> *curr you may create copy constructor/operator for each other. Normally const shouldn't be removed.
Dec 7, 2017 at 1:57pm
What makes you think so?


I tested the constructor (or at least tried to). list<int> lst(6); and list<int> lst{6}; both just give me list of size one with a Link<int> that has a value of 6. It doesn't give me what I want which is a list of size 6 initialized to 0s. As you can see, I even marked that constructor with the keyword "explicit". But that also doesn't help.

1
2
3
4
5
Since both iterator type have one member Link<Elem> *curr you may create copy constructor/operator for each other. Normally const shouldn't be removed. [/quote]  

How will copying the iterator help with erase and insert?  For reference, this is what I'm talking about: 

[quote][code]iterator insert( iterator pos, const T& value );

(until C++11)
iterator insert( const_iterator pos, const T& value );
(since C++11)
iterator insert( const_iterator pos, T&& value );
(2)
(since C++11)

(3)

void insert( iterator pos, size_type count, const T& value );
(until C++11)
iterator insert( const_iterator pos, size_type count, const T& value );
(since C++11)


(4)

1
2
template< class InputIt >
void insert( iterator pos, InputIt first, InputIt last);

(until C++11)
1
2
template< class InputIt >
iterator insert( const_iterator pos, InputIt first, InputIt last );

(since C++11)
iterator insert( const_iterator pos, std::initializer_list<T> ilist );
(5)
(since C++11)
[/quote]

(Taken from cppreference). Notice how the last two take a const_iterator as the first argument but return a normal iterator? That's the overload I want to try adding to my implementation of the class. There's also something similar for erase:

iterator erase( iterator pos );
(until C++11)
iterator erase( const_iterator pos );
(since C++11)


(2)

iterator erase( iterator first, iterator last );
(until C++11)
iterator erase( const_iterator first, const_iterator last );
(since C++11)


As for completing the class. What am I still missing? I don't have emplace and splice operations, and I also don't have an insert function that takes a double reference. What else?
Dec 8, 2017 at 8:59am
Notice how the last two take a const_iterator as the first argument but return a normal iterator?
Sure, but it is inconsistent.

It doesn't give me what I want which is a list of size 6 initialized to 0s
Acutally you have three constructors that can take a single parameter (line 172, 177, 181). Which is chosen depends on the compiler. It is the first considered matching which depends on the type of Elem. I suggest that you remove the constructor on line 172 and change the constructor on line 181 to
list(size_type count, const Elem &v);.

I even marked that constructor with the keyword "explicit".
The keyword explicit means that this constructor cannot be use in an implicit conversion.
Dec 8, 2017 at 10:22am
Okay, so wouldn't it be good to make that constructor on line 181 take a default argument as its second parameter? Although, for that, first I need to know if a default parameter can be initialized to the default value of any type T directly in the parameter list. Is this possible?

And could help me with const_iterator erase and insert functions, too, please? The erase function seems to be fine (is it?) but the insert function will have to modify a const iterator which the compiler won't allow. So what should I do there?
Last edited on Dec 8, 2017 at 10:24am
Dec 8, 2017 at 1:25pm
Okay, so wouldn't it be good to make that constructor on line 181 take a default argument as its second parameter?
While theoretically yes, it may depending on the type of Elem confuse the user of the class about what happens when you pass a single value.

Although, for that, first I need to know if a default parameter can be initialized to the default value of any type T directly in the parameter list. Is this possible?
If it has a default constructor: Yes.


And could help me with const_iterator erase and insert functions, too, please?
As I already said. One way to do this is allowing the implicit conversion from one iterator to the other:
1
2
3
4
5
6
		iterator(const_iterator it)
			: curr{ it.curr } { }
...

		const_iterator(iterator it)
			: curr{ it.curr } { }
Dec 8, 2017 at 3:45pm
Why would it cause confusion? I thought that providing a default argument like that could be a way to provide the illusion of having different constructors when there's really one constructor with the option of not providing less arguments.

Is it possible to do something like list(size_type count, const Elem &v = {}); without the compiler giving an error?
Last edited on Dec 8, 2017 at 3:46pm
Topic archived. No new replies allowed.