-1

I have an object that needs a function passed to it in order to work. Something like

int doSomething(string a, int b, string(*lookUpFunction)(string a, int b)) {
    return lookUpFunction(a,b).length():
}

This is simplified to just include needed parameters and correct return types. I believe I have defined this correctly but please correct me if I am wrong. lookUpFunction takes a string and an int and returns a string.

Where my problem comes in is using this function. I would think I would use like this

class x {
    DataBase* db;
public:
    int myFunc();
}


int x::myFunc() {
    return doSomething("a",1,[this](string a, int b)->string {
        return db->someFuncThatTakesStringAndInt(a,b);
    });
}

But my IDE throws errors. If I remove "this" it says db isn't accessible. With it in it says the lambda function is not castable to correct format.

Raymond Chen
  • 44,448
  • 11
  • 96
  • 135
  • 1
    You want the parameter to be a `std::function` rather than a function pointer. – HolyBlackCat Jun 06 '23 at 19:15
  • One of the skills you need as a programmer is to read documentation. Have a look at [introduction to lambda functions learncpp.com](https://www.learncpp.com/cpp-tutorial/introduction-to-lambdas-anonymous-functions/) then you will need to learn about function templates. And you can write something like `template auto dosomething(function_type fn){fn();};` and call it with a lambda like this : `dosomething([]{ std::cout << "this is a lambda\n"; });`. Or in your case `dosomething(std::function` is also an option. – Pepijn Kramer Jun 06 '23 at 19:16
  • See [std::function](https://en.cppreference.com/w/cpp/utility/functional/function) – Pepijn Kramer Jun 06 '23 at 19:19
  • 1
    A lambda is convertible to a function pointer *only* if it doesn't capture anything. – BoP Jun 06 '23 at 19:19
  • @BoP I was just going to say this too. So no do not try to convert lambdas to function pointers. Use a template or std::function. They are much more flexible. – Pepijn Kramer Jun 06 '23 at 19:20
  • Thanks I will have to try both the template and std function approach and see which works better. Thanks again. – Matthew Cornelisse Jun 06 '23 at 19:23
  • 1
    IMO question suffers form [XY problem](https://mywiki.wooledge.org/XyProblem). You should describe what code should do not how you try achieve that. – Marek R Jun 06 '23 at 19:29

1 Answers1

2

Your doSomething() function is taking in a plain C-style function pointer for its lookUpFunction callback.

However, a capturing lambda is not convertible to a function pointer, only a non-capturing lambda is convertible. You are capturing this, which is why you can't pass in your lambda as shown.

Instead of a function pointer, your doSomething() function will need to take in a callback object as either a std::function or a template parameter, eg:

int doSomething(string a, int b, std::function<string(string, int)> lookUpFunction) {
    return lookUpFunction(a,b).length():
}
template<typename Callable>
int doSomething(string a, int b, Callable lookUpFunction) {
    return lookUpFunction(a,b).length():
}

Now, you can pass your capturing lambda to either one.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770