learning stl difficulties

Started by
7 comments, last by snk_kid 19 years, 4 months ago
I'm finding it quite difficult to learn STL, first I found some tutorials, but I can't really seem to make much sense of them. A lot of examples use int's which don't need any setting up, not many show you how to use your own types. From what I have read so far I think you have to build your classes with STL in mind, with certain operators built in or something. One of the problems is i can't even seem to find some sort of basic overview of how things go together. I have read the basic tutorials but they don't seem to take you to any "next level", How do you know what iterators go with which class template (vector, etc)? How do you know when to use an iterator, or how to set one up? Another thing is how do you use your class functions when stored in a vector? I have worked quite hard on all this already, I thought about how I could make my code more compliant, I thought this was a good thing and would be better for STL, I thought maybe you can only use STL on simple classes or something, like you might need a list for your ships but maybe a vector for your textures, -so no good having thme all in one class, but then I find I cant use it at all? Yeah really I'm hoping to find some sort of idea on how to use STL, and some (various) things that it can do, I'm thinking along the lines of when you have; myVec:iterator...(whatever), how does that work? sorry if I went on a bit, but then if I didn't post, I wouldn't find anything out. Thanks
Advertisement
I highly recommend The C++ Standard Library : A Tutorial and Reference by Nicolai M. Josuttis.

Kuphryn
Quote:Original post by Stevieboy
A lot of examples use int's which don't need any setting up, not many show you how to use your own types.


to use your own type, just do something along the lines of std::vector<myType>

replace vector with whatever container you want to use.

Quote:Original post by Stevieboy
From what I have read so far I think you have to build your classes with STL in mind, with certain operators built in or something.


Yes you will have to overload certain operators and make certain constructors (copy contructor) depending on the container you use.

Quote:Original post by Stevieboy
One of the problems is i can't even seem to find some sort of basic overview of how things go together. I have read the basic tutorials but they don't seem to take you to any "next level",
How do you know what iterators go with which class template (vector, etc)? How do you know when to use an iterator, or how to set one up?


to get an iterator, do something along the lines of std::vector<myType>::iterator

Use an iterator when you need to iterate through the contents of a container and access the individual elements.

Example:

std::vector<myType> myVec; // assume myVec is loaded with some elementsfor(std::vector<myType>::iterator itr = myVec.begin(); itr!=myVec.end(); itr++){    *itr = 77; // iterators are pointers, so you have to dereference them to access the element}


For vectors the [] operator is overloaded, so you don't need to use iterators as much. So for vectors you can do the following instead:

std::vector<myType> myVec; // assume myVec is loaded with some elementsfor(size_t i=0; i<myVec.size(); i++){    myVec = 77;}


Quote:Original post by Stevieboy
Another thing is how do you use your class functions when stored in a vector?


ok, you lost me here.

Also, I check out SGI STL's Programmer's Guide it's a good reference.
I'd just like to concur with the original poster. SGI's site might be a good reference, but it's a poor teaching tool. And the little nuances of how things must be orginized to make them work right scares off programmers who should really be learning the STL because they fear missing one of the little things [or worse yet, not taking it into account when designing, and having to rebuild everything]

Quote:
Another thing is how do you use your class functions when stored in a vector?


I believe the OP means something like
myvec[myindex]->do_something(withX,withY);


(note: I don't actually know the STL enough to use it, and I don't know how to access class functions when the class member is stuffed in an STL container; but I hope someone understands this enough to paste the actual syntax for the OP)

STL containers overload operator[] to access elements of the container. So if you are storing pointers, e.g. in a vector&ltthing *>, you would do
container[index]->do_something(args)
. If you are storing actual objects, e.g. in a vector&ltthing *>, you would do
container[index].do_something(args)
.
Thinking in C++ Volume 2 covers the STL. I'm still going over Volume 1, but I've glanced at some of the things in V2 and it seems to go into alot of detail. Link is in my sig.
Quote:Original post by directrix
For vectors the [] operator is overloaded, so you don't need to use iterators as much. So for vectors you can do the following instead:
I wouldn't. That way you're committing yourself to using random access iterators. It's better to just use the iterator way (or algorithms if easily applicable), that way you may have the option to switch to a different container or make your code more generic. With a help of a macro you it needn't be so verbose.
using a container like:
std::vector<myType> vect;

to store your data, seems fine enough,



but when you need to traverse through it, you need:
std::vector<myType>::iterator it;

for(it = vect.begin(); it != it.end(); it++)
{
....
}

After a fine it becomes quite tedious, consider using typedefs to make it simpler:

typedef std::vector<myType> myTypeVector;
typedef std::vector<myType>::Iterator myTypeVectItr;

now the code looks a bit neater, just a suggestion, though if your writing a large application there a godsend.
Quote:Original post by Stevieboy
I'm finding it quite difficult to learn STL, first I found some tutorials, but I can't really seem to make much sense of them.
A lot of examples use int's which don't need any setting up, not many show you how to use your own types.


To understand STL better i recommend you first read about the "concepts" that STL model & use like the concepts of assignable, default constructible if you look at this table of contents go through everything related to concepts.

Quote:Original post by directrix
Quote:Original post by Stevieboy
From what I have read so far I think you have to build your classes with STL in mind, with certain operators built in or something.


Yes you will have to overload certain operators and make certain constructors (copy contructor) depending on the container you use.


There is a misconception here, no you don't have to, only when you need to, i say that because if you don't explicitly define a copy constructor & assigment operator one is implicitly generated by the compiler that does a member-wise copy, this may or may not be appropriate for user-defined type it depends on the context.

for example say you have data members that are pointers to some type, if you just left the implicitly defined copy constructor & assigmenet operator then that means a default member-wise copy/assigment so pointer members are copied/assigned that means that the new copy's members will point to same instance as the original's members did again this may or may not what you want it depends on the context.

If your user-defined type has pointer members and it aquires & releases resources for them in it's constructor & destructor, Your going to be in serious trouble if you store the actual type in STL containers because a copy is made and you'll end trying release the same resource twice or more!

So the lesson here is if you have pointer members be explicit about copy schematics here is sort guide when to do what when you have pointer members:

A. if your user-defined type permits sharing of instances (your type doesn't aquire & release resources itself) then you don't need to explicitly define the copy schematics the default implicitly defined is appropriate.

B. if your user-defined type has no meaning of copy schematics (ALA iostreams) explicitly declare your copy constructor & assigmenet operator as private and store pointers to your type in STL containers instead of the actual type.

C. Your user-defined type aquires a resource in the constructor & releases a resource in the destructor, you have 2 choices here first is you explicitly define deep-copy schematics (not just the default copy of pointers but copys of the instances they refer to). If this isn't suitable because the objects are large then refer to & use B

if i missed any please some-body add it.

Oh there is another thing some STL containers require that there types also have other certain overloaded operators but you don't have to have them in some cases you have no choice in writing them (using a library etc) or there no appropriate (when you store pointers instead of actual types), you can always use free-function/member function/functor instead with STL.

Quote:Original post by directrix
Quote:Original post by Stevieboy
Another thing is how do you use your class functions when stored in a vector?


ok, you lost me here.


I think he basically meant how to use STL algorithms with object methods.

@directrix

I'll show you an example but you'll need to read up on functors, function object adaptors & member function adaptors (member function adaptors is what you need) to understand it properly:

#include <algorithm>#include <functional> //<--- you need to include this for member function adaptors like mem_fun_ref#include <deque>#include <iostream>struct foo {   void do_bar() const {       std::cout << "hello\n";   }};int main() {   std::deque<foo> deck_of_foo(30);   std::for_each(deck_of_foo.begin(), deck_of_foo.end(), std::mem_fun_ref(&foo::do_bar));}


Quote:Original post by Stevieboy
How do you know what iterators go with which class template (vector, etc)?


All STL compliant container classes are required to provide nested public typedefs to provide type information to clients, as already been mentioned generically would be:

container_type::iterator
container_type::const_iterator

all STL compliant containers have those typedefs available.

Quote:Original post by Stevieboy
How do you know when to use an iterator


when you wont to traverse a container's elements, also iterators are required for STL algorithms, STL algorithms are generic they can work on any container with-out the need to expose there representation that implements the iterator concept.

Quote:Original post by Stevieboy
how to set one up?


generically:

container_type my_instance;//...container_type::const_iterator itr = my_instance.begin();//...


or:

container_type my_instance;//...some_stl_algorithm(my_instance.begin(), my_instance.end());//...


Quote:Original post by Stevieboy
I thought maybe you can only use STL on simple classes or something


Of course you can, read the the long story above...

[Edited by - snk_kid on November 24, 2004 4:28:37 AM]

This topic is closed to new replies.

Advertisement