Scribble, scribble, scribble

I suppose this is what they call a blog. Except that blogs are supposed to be updated more often than this is.

Feeds: Atom 1.0 (preferred), RSS 0.91. Front page: link.

< July 2005 >
SuMoTuWeThFrSa
      1 2
3 4 5 6 7 8 9
10111213141516
17181920212223
24252627282930
31      
Saturday 2005-07-09

nice clean sound

My iPod earphones went through the wash yesterday. Oops. Slightly to my surprise, they sound just about the same afterwards as they did before.

Monday 2005-07-04

poetry

More mindless link propagation. This has been done before, but never half so well: The good folk of Making Light turn spam into poetry. I believe the approved response is spelt "Squeeeeeee!".

Saturday 2005-07-02

unsaddled

Out this evening to an excellent dinner chez Sarah C. Unfortunately, at some point during the evening someone seems to have decided that s/he needed my bicycle saddle more than I did. Ah, well.

Friday 2005-07-01

why I hate c++, chapter 1

So, I have this C++ program with a class that among its other responsibilities needs to interpret textual commands from a user.

class BallOfMud {
  ...
  struct command {
    string command_name;
    string arg_spec;
    bool (BallOfMud::*func)(stuff);
  };
  ...
};

The command implementation functions are represented here as pointer-to-member so that they can act on the relevant class instance.

I find that the class has grown too big and diffuse, and decide to split it into two more coherent ones. Each of the two will be responsible for handling some of the commands. Time to split off a CommandInterpreter class, then.

Spotted the problem yet? No? Well...

class CommandInterpreter {
  ...
  struct command {
    string command_name;
    string arg_spec;
    bool (CommandInterpreter::*func)(stuff);
  };
  ...
};

class PerfectlyFormedJewel : public CommandInterpreter { ... };

Now C++'s type soundness rules say that you can't store a PerfectlyFormedJewel::* in a space designed for a CommandInterpreter::*. Why? Because the latter has to be able to do the right thing when called with any instance of CommandInterpreter pointed to by this, whereas the former might rely on being given an instance of PerfectlyFormedJewel. Aargh!

The "solution" (familiar to old C++ hands) is "Coplien's curiously recurring template pattern", whereby an instantiation of a class template can have one of its own subclasses as a template parameter:

template<typename T>
class CommandInterpreter {
  struct command {
    bool (T::*func)(...);
  };
};

class PerfectlyFormedJewel : public CommandInterpreter<PerfectlyFormedJewel> { ... };

Only you really want to make CommandInterpreter<T> inherit (excuse me, derive; this is C++, and it would never do to use standard terminology) from a non-templated superbase class, so that you don't have to put all the implementation of the damn thing into the public interface. (And also, in this particular case, for other reasons I shan't go into.) And don't get me started on what happens when you want one of these perfectly formed jewels to have subclasses of its own.

The tragic thing is that once C++ programmers are really well house-trained, their reaction on first seeing something like this is "Cool! A templated class can have one of its own subclasses as a template parameter! Just think of all the confusingsophisticated things we can do with that!", when it ought to be "What kind of idiot language requires you to put up with this kind of nonsense?".