PDA

View Full Version : A better C++ list


techbear
01-08-2006, 05:28 PM
Many moons ago, when I was still new to C++ (and still not a master of pointers), a team lead wrote a doubly linked list class, which I have used to this day.

Why? It was totally trustworthy, and it did what I wanted, as long as I understood it and cast things properly. I include links to it for your perusal, though you don't have to look at it to answer my question.
http://www.18giants.com/tests/Linklist.cpp
http://www.18giants.com/tests/Linklist.h
http://www.18giants.com/tests/Dataobje.cpp
http://www.18giants.com/tests/Dataobje.h

I no longer find this linked list to be the be-all-end-all of lists for me. I've tried to use the STL Map and List classes, but I can't get my head around them, and (to me) they don't seem to fit my new motto for 2006, "What's easiest for me?".

So please help me out. How do you handle lists (of all types, for all purposes)? Do you, like me, have some treasured list classes that you've used forever, or do you make a custom list for each type of problem? Are there some websites I can go to which demonstrate amazing and elegant list code?

Thanks!

Chozabu
01-08-2006, 06:00 PM
Only a few weeks ago i was starting to write my own linked list class, having had a quick look at the STL List and not being too keen on it.
before i really got going, i had another look at the STL... and really liked it!
It does everything i needed, and more (actauly, im not sure if it has support for tree sytle structures yet - but thats kinda low priority, as i have code for that from a while ago)

still, check
http://www.sgi.com/tech/stl/List.html - a reference

http://www.cprogramming.com/tutorial/stl/stllist.html - the last yellow box example contains most of the things you need to use


the loop looks nicer if list_iter is declared beforehand...

std::list<int>::iterator list_iter;
for(list_iter = int_list.begin(); list_iter != int_list.end(); list_iter++)
{
std::cout<<list_iter<<endl;
}

Robert Cummings
01-08-2006, 06:09 PM
It's vile really isn't it? check out blitzmax code...


For local i:int = 0 to 10
stuff...
next

and for a doubly linked list...

For local a:myclass = eachin myclass
a.x = 100
next

It's also just about as versatile as C++ as well. Can't see any use in C++ any more which is why I switched.

illume
01-08-2006, 06:23 PM
What is easiest for you... not C++. I give an example below in python.



a = [1,2,3,4]

#And to print each element of the list:
for x in a:
print x

#To get the second last element of the list(reverse indexing!):
second_last = a[-2]



http://www.pygame.org/ take a two hour challenge. Implement tic tac toe in python with pygame. Then breath in the fresh clean air. It is a language where they have applied the "What's easiest for me?" moto in its development for the last ten+ years.


.

Ronkes
01-09-2006, 01:41 AM
Although I agree that other languages have more intuitive ways to handle lists than C++ does, I'm going to assume that you don't really want to switch languages.

It's true that at first glance STL seems mighty complicated. That's mainly because of its flexibility. However, you don't need to understand everything about it to use it effectively. There are basically two things you need to know: how to create a list and how to iterate over a list.

To create a doubly-linked list of integers, just do the following.

#include <list>

std::list<int> scores;

If you need to create a list of other types of objects, just replace int with the type you need.

Iterating over the list requires you to create an iterator. An iterator is basically a pointer into the list that keeps track of where you are.

// declare the iterator
std::list<int>::iterator it;

// iterate over the list from beginning to end
for (it = scores.begin(); it != scores.end(); ++it)
{
std::cout << *it << std::endl;
}

Note the dereferencing of it inside the for-loop. You should treat it as a pointer to a list element, in this case a pointer to an integer.

The reason this code looks so daunting, is the notation. There's a very easy way to solve that: typedefs. Just create a typedef for your list type and your iterator type and everything becomes a lot easier.

#include <list>

typedef std::list<int> ScoreList;
typedef ScoreList::iterator ScoreIterator;

ScoreList scores;

for (ScoreIterator it = scores.begin(); it != scores.end(); ++it)
{
std::cout << *it << std::endl;
}

Actually, the easier notation is just a side-benefit. The real benefit is that with this method you are able to change the kind of list you use (for example, you could change ScoreList into a vector of ints, if necessary) without having to change the rest of your code.

STL is hard to beat in terms of reliability and performance. Furthermore, it's completely portable. With just the above knowledge, you should be able to make good use of it. If you start using it, though, there comes a moment you'll want to know more about it. I highly recommend the book The C++ Standard Library (http://www.amazon.com/exec/obidos/asin/0201379260/ronkes-20/) by Nicolai Josuttis.

svero
01-09-2006, 02:59 AM
One of the main problems I have with the stl is how ugly everything is under the debugger. Looking at strings or iterators in debug mode and trying to follow whats going on during an iteration or see the actual thing you want to look at while debugging is a complete nightmare. The STL suffers from trying to be everything at once and not doing any one thing very well. Its too flexible for it's own good.

Mark Fassett
01-09-2006, 03:10 AM
Svero - Visual Studio 2005 solves that ugly debugger problem.

svero
01-09-2006, 03:12 AM
Great. So all I have to do is upgrade to a new environment I dont really need for thousands of dollars. Wow.. that changes everything. Now I REALLY hate the stl.

PS : yeah i tried the free version.. lots of problems

Mark Fassett
01-09-2006, 03:18 AM
Not thousands - hundreds... And in my opinion, it's well worth it.

Dominique Biesmans
01-09-2006, 03:21 AM
One of the main problems I have with the stl is how ugly everything is under the debugger. Looking at strings or iterators in debug mode and trying to follow whats going on during an iteration or see the actual thing you want to look at while debugging is a complete nightmare.

Then you'll be happy to hear that debugging STL in visual studio 2005 has improved a lot. Look e.g. at this screenshot where I'm inspecting a std::set of Point.

edit : ah, I hadn't read the other replies yet. Well, I guess it does not make you happy then :-) I agree with Mark that an investment in vs2005 is really worth the money. (vs2005 + the latest visual assist + ankhSVN (svn plugin) is a real boost to productivity)

princec
01-09-2006, 03:29 AM
Great. So all I have to do is upgrade to a new environment I dont really need for thousands of dollars. Wow.. that changes everything. Now I REALLY hate the stl.

PS : yeah i tried the free version.. lots of problems
Go on Steve, you know you want to try that other language I keep on hassling you about ;)

Cas :)

svero
01-09-2006, 04:34 AM
Go on Steve, you know you want to try that other language I keep on hassling you about ;)

Cas :)

Is that the fancy language where after releasing 4 games the volume knobs on the options screen still don't work? I assume you need a new applet jar applet . interface jar for that. No thanks!

- S

techbear
01-09-2006, 08:31 AM
Hey, hey, now! Guys! We're REALLY exceeding the original scope of the post here. :)

I just code in C++, and wanted to know if anyone had magically good list code that I'd missed out on. After reading your replies, and doing some research of my own, the answer seems to be "No, buck up and use STL, or switch to another language". I can live with that.

Thanks!

Michael Flad
01-09-2006, 09:04 AM
Just give STL a chance - it's *way* more than just lists or containers in general and for sure you shouldn't see it as the lesser evil - it's a exceptional well done piece of software and a great gift instead.

Dig deeper into it by reading Josuttis "The C++ Standard Library: A Tutorial and Reference" (ISBN 0201379260)

milo
01-09-2006, 12:59 PM
I used to use a linked list template class in C++ a lot. Then I discovered that an array-based list was a significant performance improvement for most of the situations I was dealing with. If you find that you generally add new items to the end of the list, and only need to sort it occasionally, you might be better off with an array.

mahlzeit
01-09-2006, 01:00 PM
That's what STL's vector is for. It's an array-based list.

Viridian
01-09-2006, 07:15 PM
Yes, the STL has a bit of a learning curve and some obtuse syntax. Yes, you cannot natively look inside an STL container in Visual Studio 6 or 7 (though I'll address that in a minute).

You should still learn it. The power of the STL isn't in its containers (although they are good containers). The power lies in the algorithms, which, when properly used, can make your life so much easier it's just not believable. Every kind of sort you can think of has already been implemented, for one thing. But here's the thing that really made me love the STL:

random_shuffle(myvector.begin(), myvector.end());

Yep, with one command your container's elements have now been randomly shuffled. And because every container uses the same conventions, random_shuffle works with any container (except maps and sets, of course, where it wouldn't make much sense).

The REAL fun starts when you start writing predicates, which are functions you pass to algorithms. The most common algorithm for this is transform:

transform(myvector.begin(), myvector.end(), myvector.begin(), predicate);

"Predicate" in this case is a pointer to a function that takes the same kind of objects as your container. This function will call the predicate on each entry in the container, get the result, and then stuff those results back into the container. Of course, it could stuff them into a different container if you wanted.

And these containers will work on any data type - any of the standard ones, and any you yourself create. Yes, there's a learning hump. Do the work necessary to get over it. Someone mentioned Josuttis' "The C++ Standard Library, A Tutorial and Reference" and I agree (though you could probably get by just with Stroustrup's "C++ Programming Language" since it covers the basics of the STL). I also highly recommend Meyers' "Effectve STL", since it covers some of the STL's gotchas (like auto_ptr, which LOOKS like a smart pointer, but isn't).

Oh, and as for viewing the contents of STL containers in VC 6, this is accomplished by editing your autoexp.dat file in your Visual Studio directory. Yes, it sucks that you have to do this, but you only have to do it once, and better to light a candle, yada yada yada. Here's a link on the basics of editing your autoexp.dat:

http://www.codeguru.com/Cpp/V-S/debug/article.php/c1281

Jesse Aldridge
01-09-2006, 09:41 PM
I personally use STL, but not with any of the fancy stuff.
#include <vector>

using namespace std;

void main()
{
vector<int> nums(10);

int i;
for(i = 0; i < nums.size(); i++)
nums.at(i) = i + 1;

for(i = 0; i < nums.size(); i++)
cout<<nums.at(i)<<endl;
}
As you can see, basically just an array with bonus features: the .size() function and the automatic bounds checking, and the .resize() function are the things that make it worth it for me.

I originally learned c-style arrays and so I still find this similar way of using vectors most natural for me. I've tried the it.begin() stuff and despite having read about the advantages still prefer the more old fashioned syntax.

It's true the compiler errors can be hard to read, but you can usually just scroll the bar towards end where the more important part of the message is. And after you get used to them, they become considerably easier to read.

I also always use vectors at first. Later, if I have a bottleneck, I'll go back and switch to a map or a linked list or whatever. But I have to look up the syntax every single time.

On a similar note, I have this class that looks like this...
template<class T>
class VectorInterface
{
public:
virtual ~VectorInterface(){}

VectorInterface()
{
index = -1;
}

int size() const {return myVect.size();}
void resize(int i){ myVect.resize(i); }

T& at(int i){return myVect.at(i);}

etc...

protected:
vector<T> myVect;
}

It's basically a reimplementation of vector. Since it has a virtual destructor it can be safely derived from, which means it can serve as a jumping off point for all sorts of interesting "super vectors." For example, I derived a Pointer Vector class from this which as you might guess is a vector of pointers to a certain type of object. The vector automatically gets rid of pointers to deleted objects and stuff like that.
Lastly, this Vector Interface class allows you to include "bonus" functionality with every vector; for example I have a member function which casts the entire vector to a vector of another type.

Finally, I have several utility functions that make working with vectors easier. Here's a sampling:

template <class T>
void appendToVector(vector<T> &vect, const vector<T> &newVect)
{
int i;
for(i = 0; i < newVect.size(); i++)
vect.push_back( newVect.at(i) );
}


template <class T>
bool isInVector(const T &obj, const vector<T> &vect)
{
return find(vect.begin(), vect.end(), obj) != vect.end();
}


//Erase the passed element from the vector
//Returns the index at which it was found or -1 if it wasn't found
template <class T>
int eraseFromVector(const T &obj, vector<T> &vect)
{
if(vect.size() <= 0)
return -1;
typename vector<T>::iterator result = find(vect.begin(),vect.end(),obj);

if(result == vect.end())
return -1;

int index = result - vect.begin();
vect.erase(result);
return index;
}


template <class T>
void eraseFromVector(int i, vector<T> &vect)
{
if(vect.size() <= i)
return;
vect.erase(vect.begin() + i);
}

Bmc
01-09-2006, 10:12 PM
you really can't go wrong using STL containers. I know the syntax is intimidating at first, but trust me, once you have an idea about how STL works it's a cake walk.

svero
01-09-2006, 10:27 PM
Well I know how the STL works. I've used it since it was introduced pretty much and ended up having to debug some of the early releases with msdev where iterations and other simple things were broken. I've written code using it as recently as last year for a cross platform webserver. So to know it is not to love it.

Im guessing people here that advocate it's use just don't get what constitutes good programming. What is good code to you? That suffle works on both a vector and a list? That's crap! In my mind good programming is not about cutesy tricks and funny classes that all interleave in some fancy way. It's just the exact opposite! Good code is simple clear understandable code that doesn't lead to bugs. Its interfaces that do one thing very well and are clear and concise and well named. The STL interface is over complicated, poorly named, poorly thought out, and has a huge number of hidden complexities that can and usually do lead to bugs. (like numerous special cases that invalidate iterators for instance - good luck memorizing them all!)

No... It's not good code. I think it's a perfect example of taking a conept too far. It's too cute.. too mathy... too codey. It's an eggheads dream and a common sense developers nightmare. In a pinch you can use it for a simple container class. The most basic elements of a list are kind of ok if you wrap it all and add a bunch of typedefs. But overall it's really not great. Ever try deriving from the STL to add some of your own features to a list or vector? It's not even good OOP. I think it's a real shame it was ever made part of the standard. Maybe someone hoped it would serve as a good example of what not to do with c++.

Savant
01-10-2006, 03:04 AM
Anyone else get the impression we're about see svero go off on a rant that begins with, "Back in MY day, we..."?

Raptisoft
01-10-2006, 05:50 AM
I'm with Svero on this. I've used stl a lot too, and I always got the impression that it was set up to make it easier for non-programmers to program-- and harder for programmers to program.

mr n00b
01-10-2006, 06:52 AM
Well I know how the STL works. I've used it since....

I think you're bordering on trolling. You haven't really pointed out any specific problems with the STL besides the visual studio 4 implementation being broken and that iterators look weird when you look at them in the debugger.

The STL is being used daily by thousands of professional programmers who greatly appreciate it. The STL is one of the most well thought out pieces of software engineering ever made, and that's not just my opinion, that's a fact. Great thought went into every design decision, I suggest that you read Scott Meyers book for the reasoning behind some of them.

/mr n00b

Savant
01-10-2006, 07:18 AM
I agree for the most part. If you want to use your own classes, that's fine, but don't try to sell me on the STL being badly designed or slow or whatever. That's nonsense.

Just say that you don't want to use it and leave it at that. To do anything more is to paint yourself a fool.

Of course, ideally, other programmers would allow you to leave it at that and not try to sell you on STL afterwards but we can't win them all.

svero
01-10-2006, 04:13 PM
Well what's so great about the STL? Because when I look at it I see a poorly designed mess. I'm not trolling, and I don't think Im painting myself a fool. I feel pretty confident telling it like it is. I've coded long enough to know when something is bad and say so without fear even if it doesn't match the status quo. I don't need to follow the bandwagon simply because other people use it. Hey I know what you're probably feeling after reading those stl books. It's kinda nifty isn't it. I mean there are a lot of neato things about how the stl works. BUt then on the other hand I don't want my production code to be cute and clever. I want the shuttle to reach orbit.

You want a specific example? Ok.. you don't need me to come up with one. The web is full of em'. Here's a comparison of a basic string operation using STL vs. a Java example. (from http://www.ski-epic.com/templates_stl_rant/) One is an interface from hell and the other a nice well thought out interface. You guess which is which...

JAVA :

String filePath = "/tmp/downloaded.exe";
if ((filePath.startsWith("/tmp") && (filePath.endsWith(".exe"))
// fits the pattern.


STL

std::string filePath = "/tmp/downloaded.exe";
std::string::size_type startPos = filePath.find("/tmp", 0); // the "zero" means start from beginning
std::string::size_type endPos = filePath.rfind(".exe", filePath.size() - 1); // search from back to see if it ends in ".exe"
if ((startPos == 0) && (endPos == filePath.size() - 4))
// fits the pattern.


The 2nd example typifies part of why I don't like the STL. Although my complaints run deeper but I dont have all day to sit here typing out a book of why the STL is not so hot after all. You'll just have to eventually figure that out for yourselves. But look at those naming conventions... std::string::size_type ? I mean cmon! That's obviously really really bad. How can anyone possibly defend that? Use typedefs? Why not name it right in the first place?

Or filePath.find("/tmp", 0); 0 means start from beginning? Really bad interface. Indefensible!

And really this example is just the tip of the iceberg. Iterators get invalidated almost randomly. The stl is not easy to derive from and extend in functionality or interface. The STL is too concerned with fancy algorithms and interoperability of it's parts and not enough concerned with clear concise interfaces. etc.. etc.. etc..

I'm sorry but it's just not that good. The basics are usable if you have nothing else to work with but that's about all I'll say for it.

- S

Rainer Deyke
01-10-2006, 04:45 PM
std::string filePath = "/tmp/downloaded.exe";
std::string::size_type startPos = filePath.find("/tmp", 0); // the "zero" means start from beginning
std::string::size_type endPos = filePath.rfind(".exe", filePath.size() - 1); // search from back to see if it ends in ".exe"
if ((startPos == 0) && (endPos == filePath.size() - 4))
// fits the pattern.


The STL is more generally more concered with core functionality than cute utility function like startsWith and wndsWith (which can easily be added by the user), but you can still easily do better than that.

How about:
std::string filePath = "/tmp/downloaded.exe";
if (filePath.substr(0, 4) == "/tmp" && filePath.substr(filePath.size() - 4) == ".exe")
// fits the pattern.


If you really want to make things easy for yourself, use boost (http://boost.org):
std::string filePath = "/tmp/downloaded.exe";
if (boost::algorithm::starts_with(filePath, "/tmp") && boost::algorithm::ends_with(filePath, ".exe"))
// fits the pattern.


No changes to the STL required.

Chozabu
01-10-2006, 04:52 PM
Hmm - i like the java code there...
though STL with Boost is OK

Where are some recent Java Vs C++ speed benchmarks anyone know?
also - whats javas current status with opengl?

svero
01-10-2006, 05:14 PM
The STL is more generally more concered with core functionality than cute utility function like startsWith and wndsWith (which can easily be added by the user), but you can still easily do better than that.


I would take issue with both the characterization of a good interface as "cute" and with the phrase "easily added by" -- STL is not easy to extend. That's one of the main problems with it. And when it comes to being cute the STL wins hands down. It's nothin but cute. Core functionality.. bah... nonsense. That's just a way of saying bad interface nicely. A string class doensn't have to be ugly to have core functionality! Your substr example is "ok" but not great. The boost example is reasonable, but thats not the STL that's something someone wrote to "fix" it essentially. Everyone is always saying.. gee the stl is great just so long as you use this workaroung, and this one.. and add a little of that etc...

If the STL were a coke machine it would have 3 coin slots with labels showing which coins could go into which slots. The labels would be scratched off by vandals. To select your drink a keypad would be used to type in a code for the drink you want. The designer of the machine would argue that you can type in any code so you dont need a big pepsi button! Later maybe you want to fill it with beer or something. And everyone would nod sagely and all agree how wonderful it is that you're not tied to a few drink buttons and the machine is so versatile etc.. and then later thousands of people would go on to put the wrong coins in the slots accidentally and type in the wrong code and get drinks they didnt want.

I think if you have the judgement to tell good code from bad, and you look at the stl critically and you're being intellectually honest you won't be able to say it's a great piece of software. Anyway.. I think I've said my bit on this.. I'll let others decide for themselves what they want to use. But if you're seriously thinking of starting a major piece of software where classes like lists and strings will be used extensively (and not say just some small game where you want to store a few sprite pointers in an array) you'd best think long and hard before going the stl route.

- S

soniCron
01-10-2006, 05:20 PM
also - whats javas current status with opengl? Offtopic, but this (http://forums.indiegamer.com/showthread.php?t=5621) is where it's at.

And I'm with Steve on this one. The Java code is so much more readable and usable than even the STL with Boost code. Ideally, shouldn't it "just work?"

Viridian
01-10-2006, 07:25 PM
You want a specific example? Ok.. you don't need me to come up with one. The web is full of em'. Here's a comparison of a basic string operation using STL vs. a Java example. (from http://www.ski-epic.com/templates_stl_rant/) One is an interface from hell and the other a nice well thought out interface. You guess which is which...

JAVA :

String filePath = "/tmp/downloaded.exe";
if ((filePath.startsWith("/tmp") && (filePath.endsWith(".exe"))
// fits the pattern.


STL

std::string filePath = "/tmp/downloaded.exe";
std::string::size_type startPos = filePath.find("/tmp", 0); // the "zero" means start from beginning
std::string::size_type endPos = filePath.rfind(".exe", filePath.size() - 1); // search from back to see if it ends in ".exe"
if ((startPos == 0) && (endPos == filePath.size() - 4))
// fits the pattern.


The 2nd example typifies part of why I don't like the STL. Although my complaints run deeper but I dont have all day to sit here typing out a book of why the STL is not so hot after all. You'll just have to eventually figure that out for yourselves. But look at those naming conventions... std::string::size_type ? I mean cmon! That's obviously really really bad. How can anyone possibly defend that? Use typedefs? Why not name it right in the first place?

Or filePath.find("/tmp", 0); 0 means start from beginning? Really bad interface. Indefensible!



Really? You do know, of course, that index 0 is the first index of any array or container, right? And the biased guy who wrote the example obviously either didn't know or didn't care that if you want to find from the beginning of a string, you don't have to include an index, so he could have just used filePath.find("/tmp"). But then he wouldn't have been able to make his snarky comment.

While size_type is admittedly a bit annoying, it's made necessary by the fact that the STL must be as portable as C++ itself. If you cannot guarantee that a type is going to be the same width on every system then you have to abstract it, end of story. That is not the STL's fault.


And really this example is just the tip of the iceberg. Iterators get invalidated almost randomly.


Nope, they get invalidated under very specific conditions that you haven't bothered to learn.


The stl is not easy to derive from and extend in functionality or interface.


The STL is templated specifically to make it easy to derive from. Again, you just haven't learned how to do it.


The STL is too concerned with fancy algorithms and interoperability of it's parts and not enough concerned with clear concise interfaces. etc.. etc.. etc..


The creators of the STL had several goals in mind. Simplicity of the interface and hand-holding of programmers was not one of them. Their goal was to create a standard set of containers and a standard set of algorithms that would work on any container, as well as a standard string class.


I'm sorry but it's just not that good. The basics are usable if you have nothing else to work with but that's about all I'll say for it.


The STL was designed to be a powerful library for advanced programmers. You don't like it? Fine. But saying it's bad software...well, I'd very much like to see you or anyone else do better while following the very same strict requirements the STL's designers did.

Of course, as long as you are the sole programmer on your games you can program them however you wish. But if you ever have to team up with another programmer, don't be surprised when they ask you why you are reinventing the wheel, especially when yours is guaranteed to be less round.

And while we're doing a comparison, try this:


// Create a container of ints.
vector<int> RandVector;

// Throw in 20 ints
for(int i = 0; i < 20; ++i)
RandVector.push_back(i);

// Mix them all up.
random_shuffle(RandVector.begin(), RandVector.end());

// Print them all out - no loop necessary.
copy(RandVector.begin(), RandVector.end(), ostream_iterator<int>(cout, " "));
cout << endl;

// Sort them out.
sort(RandVector.begin(), RandVector.end());

// Print them again.
copy(RandVector.begin(), RandVector.end(), ostream_iterator<int>(cout, " "));
cout << endl;


I'd very much like to see how many lines it takes Java to do the same thing.

Laser Lou
01-10-2006, 10:36 PM
I had to chime in ... I'd like to address the issue of "goodness" in coding.
To quote Steve:
Good code is simple clear understandable code that doesn't lead to bugs. Its interfaces that do one thing very well and are clear and concise and well named. I think that most programmers agree with that, but I don't think that it's a complete description of good code. The main quality that is missing is generality. Generic code is more maintainable because it accomodates changes more quickly that specialized code. Take the Java snippet that Steve mentioned:
String filePath = "/tmp/downloaded.exe";
if ((filePath.startsWith("/tmp") && (filePath.endsWith(".exe"))
// fits the pattern. It looks more attractive than the STL based example at first glance. However, consider what would happen if the requirements changed. Suppose the "tmp" path was moved to a subdirectory, so that it started at the 8th character rather than the first. The line would have to be changed to this:
if ((filePath.substring(7).startsWith("/tmp")) && (filePath.endsWith(".exe"))) Now consider the STL version of that line from the same post, with the change:
if ((startPos == 7) && (endPos == filePath.size() - 4))
All I did there was change the "0" to "7". That's definitely simpler and more maintainable than wrapping a string with "substring". Now, this example doesn't even involve templates, but it shows how generality can make code more maintainable. I think that most agree that the STL has an abundance of generality.

Edit: Fixed the Java version of my change.

oNyx
01-10-2006, 11:35 PM
[...]
And while we're doing a comparison, try this:


// Create a container of ints.
vector<int> RandVector;

// Throw in 20 ints
for(int i = 0; i < 20; ++i)
RandVector.push_back(i);

// Mix them all up.
random_shuffle(RandVector.begin(), RandVector.end());

// Print them all out - no loop necessary.
copy(RandVector.begin(), RandVector.end(), ostream_iterator<int>(cout, " "));
cout << endl;

// Sort them out.
sort(RandVector.begin(), RandVector.end());

// Print them again.
copy(RandVector.begin(), RandVector.end(), ostream_iterator<int>(cout, " "));
cout << endl;


I'd very much like to see how many lines it takes Java to do the same thing.

Sure.

1.4 code:
import java.util.*;

public class Shuffle{
public static void main(String[]args){
ArrayList al=new ArrayList();
for(int i=0;i<20;i++)
al.add(new Integer(i));
Collections.shuffle(al);
for(int i=0;i<al.size();i++)
System.out.println((Integer)al.get(i));
Collections.sort(al);
for(int i=0;i<al.size();i++)
System.out.println((Integer)al.get(i));
}
}

Using 1.5 stuff (generics, autoboxing, static import):
import java.util.*;
import static java.lang.System.*;

public class Shuffle{
public static void main(String[]args){
ArrayList<Integer> al=new ArrayList<Integer>();
for(int i=0;i<20;i++)
al.add(i);
Collections.shuffle(al);
for(int i=0;i<al.size();i++)
out.println(al.get(i));
Collections.sort(al);
for(int i=0;i<al.size();i++)
out.println(al.get(i));
}
}

mr n00b
01-11-2006, 12:31 AM
I think any decent programmer can agree that you can write great code in both java, C#, C++, blitzmax, python etc.

The topic of this thread was 'A better C++ list' not Java vs. C++ which at least I find pretty pointless.

If you want a C++ list std::list (or one of the other containers) will probably be fine for you.

/mr n00b

gmcbay
01-13-2006, 01:17 PM
Just wanted to note that I think Steve's points are mostly valid.

I've been using the STL for years now (as a professional programmer with 11 years experience including about 8 using C++) and understand it very well and I do actually make use of it all the time because (as an example) it seems silly to write my own linked list when there is a workable one already in the standard, but that doesn't change the fact that the STL is completely obtuse and was obviously written with geeky/academic neato factor as a priority over real-world coding. I'd trade it in for rich class libraries ala Java or C# in a minute if it weren't for the runtime distribution problems those languages still have.

YMMV.

svero
01-13-2006, 06:21 PM
Just wanted to note that I think Steve's points are mostly valid.

I've been using the STL for years now (as a professional programmer with 11 years experience including about 8 using C++) and understand it very well and I do actually make use of it all the time because (as an example) it seems silly to write my own linked list when there is a workable one already in the standard, but that doesn't change the fact that the STL is completely obtuse and was obviously written with geeky/academic neato factor as a priority over real-world coding. I'd trade it in for rich class libraries ala Java or C# in a minute if it weren't for the runtime distribution problems those languages still have.

YMMV.

Exactly. I still use the stl as well sometimes. If I need a simple list Im not going to write one. But yeah I think you nailed it on the head with the geeky/academic neato factor vs real world practicality.

Michael Flad
01-13-2006, 06:58 PM
Just wanted to note that I think Steve's points are mostly valid.

I've been using the STL for years now (as a professional programmer with 11 years experience including about 8 using C++) and understand it very well and I do actually make use of it all the time because (as an example) it seems silly to write my own linked list when there is a workable one already in the standard, but that doesn't change the fact that the STL is completely obtuse and was obviously written with geeky/academic neato factor as a priority over real-world coding. I'd trade it in for rich class libraries ala Java or C# in a minute if it weren't for the runtime distribution problems those languages still have.

YMMV.

So in 8 years using C++ as a professional programmer you didn't manage to write something better? Linked lists aren't that hard to do and it isn't code you have to write again and again ... so what's the reason using almost a decade something you do not like and that would take probably 2 hours of work to replace by own code that better fits your style of coding?

techbear
01-13-2006, 09:32 PM
Okay, THAT'S easy to answer. If you're working with a team of coders, and you all agree to use STL, than you use STL, you don't force your personal style on your teammates.

Another answer; just because you CAN write something more comfortable doesn't mean you will. You can be comfortable with discomfort, if you know what I mean.

Let's all be friends, and not get into code/religious discussions. :)

I've listened to you all, and bought an STL book. Thanks for the help!!

gmcbay
01-13-2006, 11:37 PM
techbear already pretty much answered, but to confirm, the #1 reason I don't write my own linked list class for use in my professional work is that I work with a large team of other developers. Just dropping my own linked list implementation in my code wouldn't fly for all sorts of practical shared interface and political/business reasons.

Anyway, I agree with the "let's all just get along" bit... This isn't really something that can be debated with pure logic because I'm not saying the STL is broken or badly implemented (which would be easy to confirm or disprove with pure logic and testing), rather I'm saying that the interface is hideously ugly, which is a pretty subjective thing. For others, maybe the STL is quite nice... if you like it, that's great. I'm not saying you're wrong, just that your idea of nice class/library design is different than mine.

I'm personally not a huge fan of genericty (not sure if that's a real word or I'm just making it up) if the cost of that is making the API obscure to newbies and difficult to remember even if you've been using it a long time and in my opinion, the STL (and, to be fair, most other template-based libraries) takes the polar opposite of my view. I program in C++ every day at work and have extensive STL experience and I still find myself looking up the exact syntax of how to do something that is relatively simply like reverse all the characters in a string. Yeah, the STL can do it and yeah it uses a neato generic algorithm to do it that can reverse all sorts of things, not just strings, but I'll be damned if I can remember the exact syntax without looking it up. I'd be much happier calling myString.Reverse(); (particularly with the benefit of Intellisense or other code-completion technology), but to each his/her own.

(And before anyone mentions it again, yeah I know I could just have my own library of helper functions to do these things, but I'd still prefer them to just be in rich standard class libraries like .NET or Java. Again, YMMV, personal preference, etc.)

20thCenturyBoy
01-14-2006, 07:55 AM
Come on guys, what's so hard to understand about this:


transform (coll.begin(), coll.end(),
ostream_iterator<int>(cout, " "),
compose_f_gx(bind2nd(multiplies<int>(), 5),
bind2nd(plus<int>(), 10)));


Beautiful, beautiful code. :D

Savant
01-14-2006, 08:16 AM
It really is a shame we're limiting this to C++ because C#, as noted above, has some really amazing list/stack/tree classes. C# 2.0 makes all of this incredibly easy and simple to read.

HairyTroll
01-14-2006, 02:27 PM
It really is a shame we're limiting this to C++ because C#, as noted above, has some really amazing list/stack/tree classes. C# 2.0 makes all of this incredibly easy and simple to read.

Well, heck. Then we may as well throw Lisp in the mix too; but that's like playing the trump card and then the thread would be dead. :p


(defparameter *random* (loop repeat 100 collect (random 10000)))

Then the following loop will return a list containing various summary information about the numbers:

(loop for i in *random*
counting (evenp i) into evens
counting (oddp i) into odds
summing i into total
maximizing i into max
minimizing i into min
finally (return (list min max total evens odds)))

princec
01-14-2006, 02:47 PM
Anyone care to attempt the same in Brainfuck?

Cas :)

Savant
01-14-2006, 02:52 PM
Well, heck. Then we may as well throw Lisp in the mix too; but that's like playing the trump card and then the thread would be dead.
Well, C# seems related since it's the next version of C++. And, you know, usable for writing games.

HairyTroll
01-14-2006, 05:50 PM
And, you know, usable for writing games.

Oh, why don't you just kick me in the balls? :eek:

oNyx
01-14-2006, 06:21 PM
Come on guys, what's so hard to understand about this:


transform (coll.begin(), coll.end(),
ostream_iterator<int>(cout, " "),
compose_f_gx(bind2nd(multiplies<int>(), 5),
bind2nd(plus<int>(), 10)));


Beautiful, beautiful code. :D

Hm. Well, its code which *requires* comments and it also mixed 2 conventions (could be bind_2nd() aswell).

Code is about 5 times more read then written. Saving some time with typing doesnt necessarly save time at the end of the day.

Using some default library has many advantages and I pretty much agree that replacing it with something else isnt all that feasible. Fortunately my language of choice comes with some lib which suits my taste just fine (except for a handfull of minor details here and there like why its "substring" instead of "subString" or "getSubimage" instead of "getSubImage").

Uhfgood
01-14-2006, 10:42 PM
This is the kind of stuff that will scare me away from the real world of C++ and back into my cave of bad c code. (Bad C code meaning I don't feel i'm very profficient in C even though i've been programming in it almost 8 years now.)

And I should learn this language why again?

Keith

ps. I realize other languages were talked about in here but a majority was mentioning whether stl was good or not which applies to c++.

svero
01-14-2006, 11:34 PM
And I should learn this language why again?


Well I coded in straight c for quite a few years before switching to ++. It does offer many nice advantages, that once learned, would be hard to let go.

Uhfgood
01-15-2006, 12:51 AM
Well thanks for such a succinct reply. Maybe i'll continue to learn c++ then :-)

Keith