C++ Functors

People have asked me several times what I think of “functors” in C++, so I decided to form an opinion (and write it down somewhere that myself and others can refer to). I’ve also always meant to include more technical content in this blog…

My reference material on the subject was an article Chuck provided, Callbacks in C++ Using Template Functors. I felt that while it’s true that all of the functor alternatives shown in the article are obviously undesirable according to the criteria listed (and perhaps other more basic criteria, such as code readability), it doesn’t really seem to show an example of the interface-oriented (i.e. pure virtual class) model, which I believe is the purest way to solve the problem. (By pure, I mean satisfying criteria such as being object-oriented, type-safe, and non-coupled, yet not relying on void* casts and template wizardry.) Here is the example that I feel was omitted:

class Notifiable
{
public:
    virtual void notify() = 0;
}

class Button
{
public:
    void click() { if (m_pnOnClick) m_pnOnClick->notify(); }
    void onClick(Notifiable* pn) { m_pnOnClick = pn; }
private:
    Notifiable* m_pnOnClick;
}

class CDPlayer
{
public:
    void play();
    void stop();
}

class CDPlayNotifiable : public Notifiable
{
public:
    CDPlayNotifiable(CDPlayer* cdp) : m_cdp(cdp) { }
    virtual void notify() { m_cdp->play(); }
private:
    CDPlayer* m_cdp;
}

class CDStopNotifiable : public Notifiable
{
public:
    CDStopNotifiable(CDPlayer* cdp) : m_cdp(cdp) { }
    virtual void notify() { m_cdp->stop(); }
private:
    CDPlayer* m_cdp;
}

void main()
{
    CDPlayer cdp;
    CDPlayNotifiable pn(&cdp);
    CDStopNotifiable sn(&cdp);
    Button playButton;
    playButton.onClick(&pn);
    Button stopButton;
    stopButton.onClick(&sn);
    // ...
}

I believe this satisfies all but one of the “Criteria for a Good Callback Mechanism” mentioned in the article: object-oriented, type-safe, non-coupling, non-type-intrusive, and flexible. The remaining criterion, being “generic”, is of questionable validity. Obviously it’s desirable not to require the user to write repetitive support code, but I think there’s some value to explicitly defining interfaces and being able to write custom binding code. Consider, for instance, how most UI frameworks include an argument on their events that identifies the sending object. If the functor of the Button class in the article included this argument, you could no longer directly bind it directly to CDPlayer::play().

However, the code above sucks in C++ for two reasons: 1) There’s no shorthand way to provide implementations of Notifiable. (Anonymous classes in Java are great for this.) 2) Managing the lifetime of the Notifiable objects is difficult. (Again, with GC in Java, this is not an issue.) In my example, I used pointers, which necessitates ensuring that the Notifiable objects exist at least as long as the Buttons referencing them. In the functor article, this is accomplished by the functors being held by value. This makes sense for functors, which are known to be small and non-polymorphic and to implement a default constructor and operator=(). Objects implementing Notifiable may or may not be small, but more importantly, they are polymorphic and therefore cannot be held by value.

Given these difficulties, functors do seem to be a reasonable mechanism for handling callbacks in C++. I’m curious whether the memcpy() on the pointer-to-member-function in FunctorBase is kosher with regard to the C++ standard, but even if it’s not, it’s the sort of thing that always tends to work anyway.

BTW, in Java, the above code directly translates to this, which seems pretty much ideal to me:

interface Notifiable
{
    void notify();
}

class Button
{
    public void click() { if (m_onClick != null) m_onClick.notify(); }
    public void onClick(Notifiable n) { m_onClick = n; }

    private Notifiable m_onClick;
}

class CDPlayer
{
    public void play();
    public void stop();
}

void main()
{
    final CDPlayer cdp = new CDPlayer();
    Button playButton = new Button();
    playButton.onClick(new Notifiable() { public void notify() { cdp.play(); } });
    Button stopButton = new Button();
    stopButton.onClick(new Notifiable() { public void notify() { cdp.stop(); } });
    // ...
}

The Fishman Affidavit

In reading about trusted computing and censorship, I came across The Fishman Affidavit, which exposes a lot of documents concerning the upper levels of Scientology. Naturally, the Church of Scientology wants the information suppressed, but after almost 10 years of litigation, was ultimately unsuccessful. Fascinating and disturbing, it even includes Hubbard implying that Jesus was a homosexual and pedophile (in a passage that the Church itself first claimed a forgery, then asserted copyright ownership of): “the historic Jesus was not nearly the sainted figure [sic] has been made out to be. In addition to being a lover of young boys and men, he was given to uncontrollable bursts of temper and hatred”. Alrighty then…

Save NPR and PBS (again)

Everyone expected House Republicans to give up efforts to kill NPR and PBS after a massive public outcry stopped them last year. But they’ve just voted to eliminate funding for NPR and PBS—unbelievably, starting with programs like “Sesame Street.”

Public broadcasting would lose nearly a quarter of its federal funding this year. Even worse, all funding would be eliminated in two years–threatening one of the last remaining sources of watchdog journalism.

Sign the petition telling Congress to save NPR and PBS again this year:

http://civic.moveon.org/publicbroadcasting/

Read the Boston Globe story on the threat to NPR and PBS:

GOP takes aim at PBS funding

Manliness

I’ve been keeping up with this blog about as well as I’ve been keeping up with approximating a healthy lifestyle, but I must share some news with anyone bored enough to read it:

  • Maddox has written a book, The Alphabet of Manliness, that comes out June 6. I could be wrong, but this could one day be viewed as a seminal work in the underdeveloped field of Men’s Studies. (Pun contemptuously intended.) You can pre-order on Amazon for only $9.57!

  • The Height of Manly Couture
  • Browsing related books on Amazon led me to Tucker Max, author of I Hope They Serve Beer In Hell. I read his story about The Austin Road Trip and was instantly impressed. There aren’t a lot of literate assholes out there, so we must cherish the window these gifted few provide us into their world.
  • I’m returning to Austin next weekend for a visit. I don’t think I’ll have time for a road trip up to Baby Dolls, but hopefully it will be a rewarding visit nonetheless.

Habaneros Kill Cancer

My love of spicy food has been justified once more: The American Association for Cancer Research released a report today claiming that capsaicin drives prostate cancer cells to kill themselves.

According to a team of researchers from the Samuel Oschin Comprehensive Cancer Institute at Cedars-Sinai Medical Center, in collaboration with colleagues from UCLA, the pepper component caused human prostate cancer cells to undergo programmed cell death or apoptosis.

Capsaicin induced approximately 80 percent of prostate cancer cells growing in mice to follow the molecular pathways leading to apoptosis. Prostate cancer tumors treated with capsaicin were about one-fifth the size of tumors in non-treated mice.

Of course, this isn’t just a matter of sprinkling a few red pepper flakes on your pizza; the mice in the study were fed an amount of capsaicin equivalent to a 200 pound man eating 3-8 habaneros 3 times a week! ¡Muy picante!