0

Precondition:

Here is a function:

typedef std::function<void (int)> Handler;
void g(const Handler& h) {
  h(100);
}

, and a class(original version):

class A {
 public:
  A(int arg)
    : m(arg) {}

  void f0(int n) {
    std::cout << m + n << std::endl;
  }

  void f() {
    ::g(std::bind(&A::f0, this, std::placeholders::_1));
  }

 private:
  const int m;
};

And this will print two lines, '101' and '102':

int main() {
  A a1(1);
  a1.f();

  A a2(2);
  a2.f();

  return 0;
}

Now I realized A::f() will be called very frequently,
so I modified it like this(new version):

class A {
 public:
  A(int arg)
    : m(arg),
      handler(std::bind(&A::f0, this, std::placeholders::_1)) {}

  void f0(int n) {
    std::cout << m + n << std::endl;
  }

  void f() {
    ::g(handler);
  }

 private:
  const int m;
  const Handler handler;
};

My Questions:

Is it safe to bind this pointer to a member variable?

Is there no functional difference between two versions?

Can I expect the new version will really gain some performance benefit?
(I suspect my compiler(MSVC) will optimize it by itself,
so I may not need to optimize it by myself).

PS.: This question corrects and replaces the previous one: Binding member function to a local static variable

Community
  • 1
  • 1
ALittleDiff
  • 1,191
  • 1
  • 7
  • 24
  • 1
    `Is it safe to bind this pointer to a member variable?` Beware the compiler-generated copy constructor and assignment operator. Consider: `A a(42); A b = a;` Here, `b.handler` still refers to `&a`, not `&b`. This may or may not be what you want. – Igor Tandetnik Oct 24 '14 at 04:54
  • 1
    `Can I expect the new version will really gain some performance benefit?` If you really care, implement it both ways and measure. If you don't measure, then you don't really care. – Igor Tandetnik Oct 24 '14 at 04:56

1 Answers1

1

As Igor Tandetnik mentioned in comments:

Is it safe to bind this pointer to a member variable?

Beware the compiler-generated copy constructor and assignment operator. Consider:

A a(42); A b = a;

Here, b.handler still refers to &a, not &b. This may or may not be what you want.

I also don't think the performance benefit deserves dev-time effort to maintain member variables. (*)

Community
  • 1
  • 1
ALittleDiff
  • 1,191
  • 1
  • 7
  • 24