T
The Ghost In The Machine
In comp.os.linux.advocacy, Jeff Relf
<Jeff_Relf_@_NCPlus.NET.Invalid>
wrote
At least I know about C++/STL.
If one assumes the declarations
typedef std::string itemtype; // or whatever you want
typedef std::xxx<itemtype> collectiontype;
// xxx = set, vector, or list
collectiontype collection;
collectiontype::const_iterator it;
then one can do the following.
it = std::find(collection.begin(), collection.end(), "constant");
or
it = std::binary_search(collection.begin(), collection.end(), "constant");
or
inline bool myfunc(itemtype conts & val) { return val == "constant"; }
it = std::find_if(collection.begin(), collection.end(), myfunc);
or [*]
it = std::find_if(collection.begin(), collection.end(),
std::bind2nd(std::equal_to<itemtype>, "constant"));
depending on whether one has a value or a function, and whether
the collection's sorted or not. While the declarations take some
time to use properly, it should be fairly clear what I'm doing.
If the collection is a std::set<> with itemtype as the key, one can
also ask
it = collection.find(val);
which is probably simpler.
To save some typing, one can also prefix the source file with
'using namespace std;'
but I for one am not overly fond of that approach;
I prefer using 'std::' so that I can find STL usages the code.
Now, after one's assigned a value to 'it', one can then test 'it':
if(it != collection.end())
/* found it */
else
/* not in there */
or one can do inline tests such as:
if((it = collection.find("constant")) != collection.end())
/* do something with '*it' */
else
/* collection doesn't contain "constant" */
The inline assignment should be familiar to most C programmers.
One can consider 'it' a 'super-pointer', generalizing the concept
of a pointer and allowing for some nice operations. For instance,
one can remove the pointer:
collection.erase(it);
and the collection will no longer contain that item.
Dereferencing a non-end pointer ('*it') will get the item back.
collection.erase(collection.begin(), collection.end());
or just let collection go out of scope. If one wants an
explicit forest of items some work will be required to
encapsulate them properly. I have a "smartpointer" class
that contains an explicit refcount, but that does take
more space.
Your perogative. I'll say this for your way of coding:
you're close to the hot metal. However, you're also
making it ugly on yourself as you're touching the oil,
trying not to get burned by various syntactic issues,
dancing all around because of the heat, etc.
Enjoy your swamp muck, and watch out for the road tacks.
[*] This is where C++/STL starts to get a bit messy, but
std::equal_to is far more general than testfunc() -- presumably
this is documented somewhere, if only in bits/stl_algo.h
or bits/stl_function.h; note that those are included
indirectly and the user should #include <algorithm>
or #include <functional> instead.
There's a method to take a collection type and get the
type of its argument -- collectiontype::value_type
is suggested in the #include files -- if one doesn't
explicitly declare itemtype. For std::map and std::hashmap,
one can also use collectiontype::key_type.
<Jeff_Relf_@_NCPlus.NET.Invalid>
wrote
Hi The Ghost In The Machine,
You showed something like this:
for ( list_of_things_type::const_iterator
i = list_of_things.begin();
i != list_of_things.end();
i ++ )
{ const C & obj = *i;
/* ... obj ... */
}
And then you commented: <<
Compared to this level of elegance, Jeff's code is,
in the considered opinion of this particular C++ programmer,
swamp muck. ~~~ >>
Are you really a C++ programmer ? I don't think so.
At least I know about C++/STL.
Java maybe, server side perhaps,
but you're not a serious Win XP C++ programmer.
You want to make comparisons ?
This is how I loop through a list of unthread Usenet messages:
( From )
LoopC ( & Flat )
if ( Eq ( Par, ( * Arr )->Ln [ _MID ] ) ) break ;
If one assumes the declarations
typedef std::string itemtype; // or whatever you want
typedef std::xxx<itemtype> collectiontype;
// xxx = set, vector, or list
collectiontype collection;
collectiontype::const_iterator it;
then one can do the following.
it = std::find(collection.begin(), collection.end(), "constant");
or
it = std::binary_search(collection.begin(), collection.end(), "constant");
or
inline bool myfunc(itemtype conts & val) { return val == "constant"; }
it = std::find_if(collection.begin(), collection.end(), myfunc);
or [*]
it = std::find_if(collection.begin(), collection.end(),
std::bind2nd(std::equal_to<itemtype>, "constant"));
depending on whether one has a value or a function, and whether
the collection's sorted or not. While the declarations take some
time to use properly, it should be fairly clear what I'm doing.
If the collection is a std::set<> with itemtype as the key, one can
also ask
it = collection.find(val);
which is probably simpler.
To save some typing, one can also prefix the source file with
'using namespace std;'
but I for one am not overly fond of that approach;
I prefer using 'std::' so that I can find STL usages the code.
Now, after one's assigned a value to 'it', one can then test 'it':
if(it != collection.end())
/* found it */
else
/* not in there */
or one can do inline tests such as:
if((it = collection.find("constant")) != collection.end())
/* do something with '*it' */
else
/* collection doesn't contain "constant" */
The inline assignment should be familiar to most C programmers.
One can consider 'it' a 'super-pointer', generalizing the concept
of a pointer and allowing for some nice operations. For instance,
one can remove the pointer:
collection.erase(it);
and the collection will no longer contain that item.
Dereferencing a non-end pointer ('*it') will get the item back.
This is how I delete a forest of threaded messages:
DeC ( Lnk_T Lnk ) { if ( ! Lnk->B ) return ;
LoopC ( Lnk ) { Lnk_T P = * Arr ;
// Recursively deletes... how fun.
DeC ( P );
// Deletes the array of lines that contain
// the abbreviated headers.
LineArr Ln = P->Ln - 1 ;
Loop( _Lns ) free ( * ++ Ln ); free ( P ); }
free ( Lnk->B ); }
collection.erase(collection.begin(), collection.end());
or just let collection go out of scope. If one wants an
explicit forest of items some work will be required to
encapsulate them properly. I have a "smartpointer" class
that contains an explicit refcount, but that does take
more space.
I'm looking at your way... and my way...
I'm comparing the two, and I'm very much preferring my way.
Your perogative. I'll say this for your way of coding:
you're close to the hot metal. However, you're also
making it ugly on yourself as you're touching the oil,
trying not to get burned by various syntactic issues,
dancing all around because of the heat, etc.
By the way...
People are Still inventing wheels... as they well should.
It's called: A better tire.
Enjoy your swamp muck, and watch out for the road tacks.
[*] This is where C++/STL starts to get a bit messy, but
std::equal_to is far more general than testfunc() -- presumably
this is documented somewhere, if only in bits/stl_algo.h
or bits/stl_function.h; note that those are included
indirectly and the user should #include <algorithm>
or #include <functional> instead.
There's a method to take a collection type and get the
type of its argument -- collectiontype::value_type
is suggested in the #include files -- if one doesn't
explicitly declare itemtype. For std::map and std::hashmap,
one can also use collectiontype::key_type.