Chicago C/C++ Users Group Message Board › Class templates with integer parameter

Class templates with integer parameter

Conrad W.
CWeisert
Chicago, IL
Post #: 28
November's discussion inspired me to write a little article
http://www.idinews.co...­
about a use of class templates that gets overlooked in many textbooks and courses. If the group is interested, I'd be glad to prepare a short (30-40 minute) presentation including actual code.
A former member
Post #: 3
I'm interested!
A former member
Post #: 25
I think that would be a good backup to the templates exercise scheduled for the next meeting. I don't know how long the exercise will take so if you can have that ready it would be great. If we don't get to it we can schedule it as the primary activity for the next meeting.
Conrad W.
CWeisert
Chicago, IL
Post #: 29
I'm sorry that an injury I incurred over the weekend renders me too immobile to attend the January 26 meeting. In case you need more material to fill the time, however, I prepared a little demonstration of the contiguous string class. See (or, better, print) the 3-page listing at
http://www.idinews.co...­
It shows a USE of Cstring, but not the Cstring code itself, which I want to modify before presenting it. The current version predates the STL string class, and uses an in-house-developed Dstring class instead. I'll prepare a verstion that uses the STL string class and, if the group is interested, I'll present it in February or March.

The old (1994) version of this PersonName class has a couple of flaws that ought to be corrected. If you're interested in a little exercise, you might try to spot (and fix) them and also to visualize the underlying Cstring class that makes this work.

The article that motivated this was
http://www.idinews.co...­
and additional relevant background on string classes is
http://www.idinews.co...­

I'm eager for the group's comments.
Conrad W.
CWeisert
Chicago, IL
Post #: 32
Since I got no comments I assume last night's meeting, small as it was, didn't get around to my little example.
http://www.idinews.co...­
However, a couple of very small aspects of that example may elicit some useful discussion following up on templates. In the test-driver program on page 3 the if statement uses two template functions that aren't shown in the listing: operator> and swap.

Those members who haven't made much use of template functions may find it interesting to reconstruct the code that that made this program work.

All members may want to weigh in on whether such global templates (They're obviously defined in "global.hpp") are a positive or negative contribution to program maintenance and understandability.

None of that was the main purpose of the example, but it's a manageable topic for online discussion.

Nevin ".
nliber
Libertyville, IL
Post #: 10
For operators, I tend to use the Boost.Operators library, which gives me fine grain control over exactly which operators I want in a way that is self documenting.

(There are times where I define an operator< say, to store it in a set or a key in a map, but I don't want the other operators, as the ordering I have given it doesn't make sense outside of that context.)

The way it gets used is:

class PersonName : private boost::less_than_comparable<PersonNam­e>
{
public:
bool operator<(PersonName const& r) const { /* ... */ }
};

This gives me >=, > and <= written in terms of <.

The (simplified) way it works is:

template<typename T>
class less_than_comparable
{
friend bool operator>(T const& l, T const& r)
{ return r < l; }

friend bool operator<=(T const& l, T const& r)
{ return !(r < l); }

friend bool operator>=(T const& l, T const& r)
{ return !(l < r); }
};

An alternative would be std::rel_ops found in <utility>, but I much prefer the Boost library.

Conrad W.
CWeisert
Chicago, IL
Post #: 33
Yes, that's the way I did it, too, except that the >, <+, and >= functions are independent function templates and don't need to be friends of any class.

I'm uncomfortable with a class for which less_than is defined but not the other relationals. It seems to violate the mathematical meaning of the relations.

Rene R.
grafikrobot
Evanston, IL
Post #: 1
I can understand being uncomfortable with not having the other operators but there are practical and mathematical reasons to just having specific relations. Specifically when comparing things like ranges and sets. We have to remember that the C++ operators are not just about number math.
Conrad W.
CWeisert
Chicago, IL
Post #: 34
Well, two members have now asserted that there are contexts in which a < b is not equivalent to b > a, but we haven't yet seen an example of such a context. Until I see such an example, I remain doubtful.

The Java community continues to assert that non-intuitive overloaded operators impair program readability.
(See http://www.idinews.co...­) Doesn't a class that violates the laws of mathematics bolster their position?
Nevin ".
nliber
Libertyville, IL
Post #: 11
Concrete example: We have a client server based system where we use the machine MAC address as the key. This needs to be used as a key in a std::map. Initially it looked something like this:

class MACAddress : boost::equality_comparable<MACAddress­>
{
// ...
friend operator<(MACaddress const& lhs, MACAddress const& rhs)
{ return std::lexicographical_compare(lhs.addr.be­gin(), lhs.addr.end(), rhs.addr.begin(), rhs.addr.end()); }

boost::array<char, 6> addr;
};

This ordering is a strict weak ordering, so it can be used as keys in STL associative containers.

But how much sense does it make outside of that context? Heck, just change the compiler option flipping the signedness of char, and the ordering changes.


Next we observed that while the manufacturer of the hardware rarely changes (the first couple of bytes of a MAC address), the numbering of them does (the last few bytes), so to speed the checks up, we did the compare in reverse order, as in:

friend operator<(MACaddress const& lhs, MACAddress const& rhs)
{ return std::lexicographical_compare(lhs.addr.rb­egin(), lhs.addr.rend(), rhs.addr.rbegin(), rhs.addr.rend()); }

This changed the ordering to something that really doesn't make sense for anyone, but it still meets the STL associative container requirement that there be a strict weak ordering.


We then changed it again. Since number comparisons are faster than byte comparisons, and we could afford an extra two bytes per instance, it became:

class MACAddress : boost::equality_comparable<MACAddress­>
{
// ...
friend operator<(MACaddress const& lhs, MACAddress const& rhs)
{ return lhs.asNumber < rhs.asNumber; }

union
{
boost::array<char, 6> addr;
unsigned long long asNumber;
};
};

(One of the few times I've used a union.) Now, not only is the ordering really nonsensical (although it is still a strict weak ordering), but can vary based on things like the endianness of the machine.
Powered by mvnForum

Sign up

Meetup members, Log in

By clicking "Sign up" or "Sign up using Facebook", you confirm that you accept our Terms of Service & Privacy Policy