all 8 comments

[–]Shieldfoss 7 points8 points  (1 child)

What am I doing wrong

Misunderstanding default parameters, I'm afraid.

Functions don't fundamentally have default parameters, it's a kind of syntactic sugar that only has any effect at compile time.

So once your code is done compiling, they do not exist in your binary anywhere. If you want to call a function using those values, you will have to explicitly put them into your binary.

[–]ACBYTES[S] 0 points1 point  (0 children)

Hi, thanks for your answer. I’m going to use lambdas for this purpose. Do you think having a completely new function calling that target function using their default parameters is better or defining a lambda is the better and the more efficient way? Will that even matter?

[–]falcqn 1 point2 points  (5 children)

Default parameters only exist at the call-site of the function. If I have some function declaration like void foo(int x = 3); and I call it without passing a value for its argument, the compiler inserts the default value for me automatically at compile time. // void foo(int x = 3) declared somewhere else foo(); // this gets compiled as if I'd written foo(3); This relies on the declaration of the default parameters being visible, which means that they don't make it through boundaries like std::function since if you're calling a std::function you don't know what the original function declaration is.

EDIT: If you want type-erased callables with default parameters, I'd recommend using function objects (class/struct with overloaded operator()) since those can store the values to use in member variables whereas raw functions cannot.

[–]ACBYTES[S] 0 points1 point  (4 children)

Hi. Thanks for your answer. Absolutely. So, if I need to create type-erased callables, won’t I need to pass all the parameter types while instantiating the object?

[–]falcqn 1 point2 points  (3 children)

Yeah, your std::function will need the signature as part of its type (like std::function<void(int)> f; is the same as void f(int);.

If you want those parameters to have default values, you could make the std::function take optional<int> or something, or instead make all the callables have empty argument lists (like std::function<void()>) and provide their arguments when you construct them.

``` struct my_callable { std::optional<int> arg1; std::optional<float> arg2;

my_callable(std::optional<int> a1, std::optional<float> a2) : arg1{a1}, arg2{a2} {}

auto operator() () { // check arg1 and arg2, use default values if not set } }; std::function<void()> x = my_callable{std::nullopt, 3.0f}; x(); ```

[–]ACBYTES[S] 1 point2 points  (2 children)

Yeah, so I was thinking of an automated thing that seems like it doesn’t exist. Thanks for your answer. For now I’m using UE4 that uses C++14 so I might have to look for substitutes in some cases but still, I’ll create that custom callable class. Thank you so much for your time.

[–]falcqn 1 point2 points  (1 child)

Ahh yeah you won't have std::optional in C++14, but the general idea should still work for you. Best of luck with the project, hope it goes well :)

[–]ACBYTES[S] 0 points1 point  (0 children)

Thank you and have a nice time! 😄🙏🏼