Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » C++ Alternatives to Arrays

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
C++ Alternatives to Arrays
Michael Jensen
Member #2,870
October 2002
avatar

I've been using .NET forever now, and with speedhack comming up, I want to get back into the feel of C++.

.NET has spoiled me with it's super easy generic collections (System.Generic.Collections) Where you can declare in VB "List(Of String)" or "List(Of Integer)" or "List(of List(of MyType))" ooh and dictionaries too!

Basically a list collection is strongly typed and starts out empty (it has a Count property that tells you how many items there are in the collection, and you can refer to your items by property), and you add items to it with it's Add method, and remove them with the RemoveAt or Remove (removeat takes an index, and remove takes a pointer to the item.)

I think these types of collections already exist in C++ (but I'm more of a C programmer, so I've never known about them.) I could write the collection myself if it doesn't exist, but it'd be more convient if I understood the C++ equivalent of generics (am I wrong in assuming C++ templates can do this?)

[/n00b] 8-)

Goalie Ca
Member #2,579
July 2002
avatar

-------------
Bah weep granah weep nini bong!

BAF
Member #2,981
December 2002
avatar

STL does that, but .NET's Generics are, IMO, more powerful and nicer to use.

Michael Jensen
Member #2,870
October 2002
avatar

:: learning about vectors now ::

yeah, I figured .NET would be nicer, but I had also figured C++ had at least something comparable that's at least easier than arrays or linked lists.

Thanks guys! :D

Goalie Ca
Member #2,579
July 2002
avatar

I should have also mentioned that it's useless to learn STL without the algorithms as well.

http://cppreference.com/cppalgorithm/index.html
It also adds a flare of functional programming to C++.

-------------
Bah weep granah weep nini bong!

Michael Jensen
Member #2,870
October 2002
avatar

Wow, you're a fucking mind reader! :D

My next question was: How do I swap items around in a list, and how do I sort them, etc... ;D

Roberto
Member #7,391
June 2006
avatar

Can you do this in .NET? :)

#include <boost/spirit/phoenix.hpp>

// lets find if there is some odd numbers here...
if ( find_if(c.begin(), c.end(), arg1 % 2 == 1) != c.end() ) {
   // yap, there is something odd here ;-)
}

See http://spirit.sourceforge.net, and go to Phoenix (library).

By the way, you are not using C++ if you don't use libraries, STL is the basic one, but there is much more... see http://www.boost.org too.

How to sort:

#include <vector>
#include <algorithm>
vector<string> c;
// ...
sort( c.begin(), c.end() );

Very easy. To swap use "swap" and "swap_range", although with all those algorithms out of the box, it isn't needed so much.

Michael Jensen
Member #2,870
October 2002
avatar

to be honest, I don't know what that does, but I'm guessing it loops through all of the items from 0 to size-1... and checks for odd numbers, returns true if there is one? You could write a quick function to do it; it doesn't look like anything special? Am I wrong?

edit: Next question, is there something similar to a dictionary built into STL/C++?

Dictionaries in .NET basically have two types, a key type and a value type, so you can have a dictionary of (void *) where the key is a string, and you could access the data something like this MyDictionary["XYZ"] = new MyType(); or MyType x = MyDictionary["XYZ"];

Roberto
Member #7,391
June 2006
avatar

It's not special, it is amazing!!!!

You can put the function body while you call the algorithm, it's functional programming at its best..., for me, it is great! :)

The find_if function will return an iterator to the first element that meet the requirement (which can be any function), if there is no one, it will return the second parameter (i.e. an iterator to the end of the range), this is why I put " ... != c.end()", the condition will be true if there is at least one element which is odd.

EDIT: Yes, there is a dictionary, but it is called a "map":

#include <map>

map<string, int> distances;

distances["Canada"] = 500;

BAF
Member #2,981
December 2002
avatar

What is that code supposed to do? To be honest, I don't really like Boost (not that I've ever used it) because it's soooo huge and bloated to be useful.

But whatever that code does, I'm sure I could post a short equivalent in C#. Just explain the code. :P

[edit] Didn't see your post before I posted. Anyway, .NET 3.0 has lamdba (or however you spell it) so you can send anonymous functions to another function, or call them. Nicer than your Boost stuff. :P

Matthew Leverton
Supreme Loser
January 1999
avatar

You could always use D/DAllegro if you're just concerned about Speedhack.

Michael Jensen
Member #2,870
October 2002
avatar

Quote:

You can put the function body while you call the algorithm, it's functional programming at its best..., for me, it is great!

Well, .NET run's as IL code, the LUA implementation supports it for sure (as that's part of LUA), but I'm guessing VB/C# don't. Anyone could write a .NET language that supported it though.

Edit:

Quote:

Use D![snip]

I considered it, but my favorite debug tools/intellisense (read lazy coder GUI) don't support D (MSVC) ... I'll compile with GCC/MSVC for now, as I imagine good debugging utils are going to save me loads of time.

Edit2: If good visual editors/debuggers/intellisense have been developed in the D scene, then I might reconsider.

Roberto
Member #7,391
June 2006
avatar

Quote:

I don't really like Boost (not that I've ever used it) because it's soooo huge and bloated to be useful.

The boost library is really a collection (20+) of libraries, so you just pick the one you want to use, they are not big, really, most of them are just "header only" libraries, and very useful, shared_pointer and lexical_cast comes to my mind.

I've explained the code in the EDIT part ;)

By the way, I'll check D/DAllegro

Michael Jensen
Member #2,870
October 2002
avatar

Thanks

Goalie Ca
Member #2,579
July 2002
avatar

Quote:

Didn't see your post before I posted. Anyway, .NET 3.0 has lamdba (or however you spell it) so you can send anonymous functions to another function, or call them. Nicer than your Boost stuff.

C++0x is going to be adding lambda expressions.. sadly the ones from boost/lambda :( It is a step up from std::bind1st and std::plus etc. but it is clearly a hack of the worst kind. The most evil part: COMPILER ERRORS!1111

C# 3.0 has added lambda expression from what i can tell. I really really wish c++ allowed that kind of anonymous functions.

-------------
Bah weep granah weep nini bong!

Michael Jensen
Member #2,870
October 2002
avatar

Ok, I'm screwing up the map's iterator here, having some problems, what am I doing wrong?

  map <string, double> Dict;

  Dict["Hello World"] = 52.5;
  Dict["PI"] = 3.14159;
  Dict["Your Mom's"] = 5318008;
  

  for (map<string, double>::iterator i=Dict.begin(); i != Dict.end(); i++)
  {
    //I'm assuming first = key, and second = value -- this must be wrong...
    printf("%s = %f\n", i->first, i->second);
  }

Matthew Leverton
Supreme Loser
January 1999
avatar

double[string] Dict;
Dict["Hello World"] = 52.5;
Dict["PI"] = 3.14159;
Dict["Your Mom's"] = 5318008;
  
foreach(key, val; Dict)
{
  writefln("%s = %s", key, val);
}

8-)

Quote:

Edit2: If good visual editors/debuggers/intellisense have been developed in the D scene, then I might reconsider.

But no, D doesn't have a very advanced toolset to work with. But I'd rather use it without, than use C++ with. :P

I use UltraEdit with syntax highlighting and the standard gdb debugger.

Michael Jensen
Member #2,870
October 2002
avatar

fucking D. >:(

edit: does ultraedit give you intellisense?

edit2: Someone aughta write a .NET implementation of D already. :-X

Goalie Ca
Member #2,579
July 2002
avatar

I wrote this piece of code. Compiled and worked first try :D *which is rare for me in c++ sadly.

Btw.. pair is a tuple of size 2.

1 1 #include <map>
2 2 #include <iostream>
3 3 #include <string>
4 4 using namespace std;
5 5
6 6 void print_pair(const pair<string,double>& p)
7 7 {
8 8 cout<<p.first<<" = "<<p.second<<endl;
9 9 }
10 10
11 11 int main(int argc, char** argv)
12 12 {
13 13 map <string, double> Dict;
14 14
15 15 Dict["Hello World"] = 52.5;
16 16 Dict["PI"] = 3.14159;
17 17 Dict["Your Mom's"] = 5318008;
18 18
19 19 for_each(Dict.begin(),Dict.end(),print_pair);
20 20 return 0;
21 21 }

if i inline print_pair using boost/lambda it will look like this. Notice how boost lambda sucks balls for even a simple example.

1 1 #include <map>
2 2 #include <iostream>
3 3 #include <string>
4 4 #include <boost/lambda/lambda.hpp>
5 5 #include <boost/lambda/bind.hpp>
6 6
7 7 using namespace std;
8 8 using namespace boost::lambda;
9 9
10 10 typedef map<string, double> Dict;
11 11 typedef Dict::value_type DictPair;
12 12
13 13 int main(int argc, char** argv)
14 14 {
15 15 Dict d;
16 16
17 17 d["Hello World"] = 52.5;
18 18 d["PI"] = 3.14159;
19 19 d["Your Mom's"] = 5318008;
20 20 //notice how boost lambda absolutely sucks!
21 21 for_each(d.begin(),d.end(),cout << bind(&DictPair::first, _1) << " = " << bind(&DictPair::second, _1) << "\n");
22 22 return 0;
23 23 }

-------------
Bah weep granah weep nini bong!

Michael Jensen
Member #2,870
October 2002
avatar

Goalie CA, your code failed in the same way mine did and then I realized that I had been doing it right all along, well, sort of... here's what I had to change:

//printf("%s = %f\n", i->first, i->second);
printf("%s = %0.2f\n", i->first.c_str(), i->second);

The keys I can expect would have been wrong, but I still don't understand why the values themselves were wrong when printed... oh well, fixed now.

Thanks everyone, happy speed hacking when the time comes. :-)

ImLeftFooted
Member #3,935
October 2003
avatar

C++'s has a crap load of list features. I've never used a language with more.

{"name":"containerchoice.png","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/c\/0c0f8b542e5ce053a092a917da542369.png","w":684,"h":707,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/0\/c\/0c0f8b542e5ce053a092a917da542369"}containerchoice.png

std::set is (i think) the coolest. Mainly due to its weirdness. std::multi_set is ofcourse even stranger o_O

Michael Jensen
Member #2,870
October 2002
avatar

:o

edit: When overloading the subscript operator ([]), how do you account for assignment? All I can write is a getter, not a setter.

  double operator[](int idx)
  {
    if (idx==0){return this->x;}
    if (idx==1){return this->y;}
    if (idx==2){return this->z;}
    return 0;
  }

Jonatan Hedborg
Member #4,886
July 2004
avatar

That's a neat flowchart dustin, geeky (it being a flowchart about STL containers), but neat. Of those i often use vector, list, deque and map.

Doesn't Java have the exact same containers (only with slightly different names)?
Hmm. maybe it lacks multi_set/multi_map (they are pretty much just a map<yourkey,vector<yourvalue> > anyway).

Goalie Ca
Member #2,579
July 2002
avatar

Quote:

edit: When overloading the subscript operator ([]), how do you account for assignment? All I can write is a getter, not a setter.

Well have the [] return a reference to the element rather than a copy.

-------------
Bah weep granah weep nini bong!

GullRaDriel
Member #3,861
September 2003
avatar

A good alternative to C++ arrays:

Use the Glib !

Manual

Table of Contents

GLib Fundamentals

* Basic Types — standard GLib types, defined for ease-of-use and portability.
* Limits of Basic Types — portable method of determining the limits of the standard types.
* Standard Macros — commonly-used macros.
* Type Conversion Macros — a portable method for storing gint & guint values in gpointer variables.
* Byte Order Macros — a portable way to convert between different byte orders.
* Miscellaneous Macros — specialised macros which are not used often.

GLib Core Application Support

* The Main Event Loop — manages all available sources of events.
* Threads — thread abstraction; including mutexes, conditions and thread private data.
* Dynamic Loading of Modules — portable method for dynamically loading 'plug-ins'.
* Memory Allocation — general memory-handling.
* IO Channels — portable support for using files, pipes and sockets.
* Message Output and Debugging Functions — functions to output messages and help debug applications.
* Message Logging — versatile support for logging messages with different levels of importance.

GLib Utilities

* String Utility Functions — various string-related functions.
* Date and Time Functions — calendrical calculations and miscellaneous time stuff.
* Hook Functions — support for manipulating lists of hook functions.
* Miscellaneous Utility Functions — a selection of portable utility functions.
* Lexical Scanner — a general purpose lexical scanner.
* Automatic String Completion — support for automatic completion using a group of target strings.
* Timers — functions to time operations.
* Windows Compatability Functions — functions to support portability to the Windows environment.

GLib Data Types * Memory Chunks — efficient way to allocate groups of equal-sized chunks of memory. * Doubly-Linked Lists — linked lists containing integer values or pointers to data, with the ability to iterate over the list in both directions. * Singly-Linked Lists — linked lists containing integer values or pointers to data, limited to iterating over the list in one direction. * Hash Tables — associations between keys and values so that given a key the value can be found quickly. * Strings — text buffers which grow automatically as text is added. * String Chunks — efficient storage of groups of strings. * Arrays — arrays of arbitrary elements which grow automatically as elements are added. * Pointer Arrays — arrays of pointers to any type of data, which grow automatically as new elements are added. * Byte Arrays — arrays of bytes, which grow automatically as elements are added. * Balanced Binary Trees — a sorted collection of key/value pairs optimised for searching and traversing in order. * N-ary Trees — trees of data with any number of branches. * Quarks — a 2-way association between a string and a unique integer identifier. * Keyed Data Lists — lists of data elements which are accessible by a string or GQuark identifier. * Datasets — associate groups of data elements with particular memory locations. * Relations and Tuples — tables of data which can be indexed on any number of fields. * Caches — allows sharing of complex data structures to save resources. * Memory Allocators — allocates chunks of memory for GList, GSList and GNode.

"Code is like shit - it only smells if it is not yours"
Allegro Wiki, full of examples and articles !!

 1   2   3 


Go to: