2

Let this code tell the story (or watch the showterm):

#include <iostream>

int foo(bool func (void)) {
  int i; for (i = 0; i < 10 && func(); i++);
  return i;
}

int main() {
  std::cout << foo([] {
    return true;
  }) << std::endl;

  bool a = false;
  std::cout << foo([&a] { // error: no matching function for call to 'foo'
    return a = !a;
  }) << std::endl;

  return 0;
}

I expect to be able to capture a within my lambda, and be able to alternate the return value. My actual case has much more involved, but it boils down to that. I'd like to be able to use lambdas, though the alternative would be using a plain function with a global variable to hold the state.

I'm compiling with:

clang++ -std=c++11 testcase.cc

I'm using Apple's LLVM:

Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix

Is this a bug, or am I doing something wrong?

Jan Segre
  • 574
  • 5
  • 12

1 Answers1

7

You can convert lambda to function pointer (bool func (void)) if and only if it does not capture anything. So first part compiles but second part won't.

You should use std::function

#include <functional>

int foo(std::function<bool(void)> func) {
  int i; for (i = 0; i < 10 && func(); i++);
  return i;
}

or template

template <class TFunc>
int foo(TFunc && func) {
  int i; for (i = 0; i < 10 && func(); i++);
  return i;
}
Bryan Chen
  • 45,816
  • 18
  • 112
  • 143
  • That was it. I don't know how I didn't find the original question. – Jan Segre May 21 '14 at 05:41
  • You'll want to take `func` by value, "universal reference," or const reference; the result of evaluating a lambda expression is a prvalue, so `TFunc &` won't work. – Stuart Olsen May 21 '14 at 07:12