c++lambdainitializationbraced-init-list

Can't construct std::function with brace initialization


EDIT: I was being dumb. The functionMaker call is shockingly a function not a constructor, so the braces obviously don't work.

So I have what is basically a factory function for producing a std::function from int to int, a quick minimal example is

std::function<int(int)> functionMaker(int x) {
    return [x](int foo){return foo*x;};
}

Basically, I want to bind some values into the function (kind of like currying), and then call it later.

I want to use it through something like

functionMaker{2}(10)

But it errors me.

I verified that

functionMaker(2)(10)

works

And I explored what happens if I stored the function and then called it.

auto fct = functionMaker{2};
std::cout << fct(10) << std::endl;

fails, but

auto fct = functionMaker(2);
std::cout << fct(10) << std::endl;

works.

So it seems like braces just don't work here. What's going on? To reiterate, I would like to call it with something like functionMaker{2}(10). This way it's a bit easier for me to read which part is the construction and which part is the calling. What am I missing here?


Solution

  • If you'd like functionMaker{} to work, then functionMaker needs to be a class/struct. Functions can only take arguments via (). However, it's relatively easy to make it a class:

    struct functionMaker
    {
        functionMaker(int x)
        : f([x](int foo){return foo*x; }) {}
    
        int operator()(int foo) { return f(foo); }
        std::function<int(int)> f;
    };
    

    It's a bit more clumsy, but you only need to write it once; you can even generalize it to be like, make_functionMaker(f, ...).

    Note that you can save std::function's overhead by simply implementing the function in operator().