Subject: [boost] [function] Documentation suggestion (FAQ)
From: Evan Driscoll (driscoll_at_[hidden])
Date: 2013-01-31 12:31:34


I just wrote up a longish email (excerpted below) that was basically
asking for advice about how to work around the fact that I can't compare
two function objects. However, I fortunately decided to take another
look at the docs before sending, and realized that Boost actually
supports what I *really* needed, which was to compare a function object
to see if it points to a particular function so I could use a much
faster implementation.

In other words, I was doing
    void backing_func() {...}
    boost::function<void()> func(backing_func);

    void foo(function<void()> callback) {
        if (callback == func) {
            fast_foo();
        } else {
            slow_foo(callback);
        }
    }
but by changing the if statement condition to
    if (callback == &backing_func)
everything is fine and dandy.

My suggestion is that the FAQ entry at
http://www.boost.org/doc/libs/1_52_0/doc/html/function/faq.html should
be updated to point out that there IS a way to do this specific case. If
everyone read the whole docs and remembered them perfectly this wouldn't
be a problem, but of course those statements are probably true of
exactly no one. :-) I stumbled across the FAQ entry, which I feel
strongly suggests that what I want to do is impossible.

Evan

P.S. If you have suggestions for a better design, I'm open to suggestions.

---------

I'd like input about how to handle a design. I'll describe what I'm
doing; my question is what people would suggest.

I have a class which stores a boost::function<> as a parameter so as to
provide a hook to customize its behavior. I can give the actual code and
description of what I'm doing if that will help, but I suspect it
distract more than help, so I'll just make something up (untested):

  typedef boost::function<bool (int, int)> CallbackType;

  class MyClass {
      CallbackType callback;

      void foo() {
          ...
          if (callback(x, y)) {
              ....
          }
      }

      MyClass(CallbackType cb) : callback(cb) {}
  };

There are a couple generically useful behaviors, so the library
predefines callbacks for those:

   bool behavior_a(int, int) {...}
   bool behavior_b(int, int) {...}
   bool behavior_c(int, int) {...}

   CallbackType behavior_a_callback(behavior_a),
                behavior_b_callback(behavior_b),
                behavior_c_callback(behavior_c);

I have need to make 'foo' fairly general and support fairly general
callbacks, but for one behavior (say behavior_a), I can use a
substantially more efficient algorithm (log or constant time, instead of
linear) inside foo(). What I WANTED to do was make the
behavior_a(int,int) function just a dummy, then do

   void foo() {
      if (callback == behavior_a_callback) {
         fast_foo();
      }
      else {
         slow_foo();
      }
   }

However, for reasons described at
http://www.boost.org/doc/libs/1_52_0/doc/html/function/faq.html#id1617166,
you can't compare functions with equality.

Any thoughts as to how you'd do this?

Evan