How to call a function with default parameter through a pointer to function that is the return of another...





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







14















I have functions Mult, Add, Div, Sub, Mod those takes two integers and returns the result of its parameters. And a function Calc that takes a character as an Operator and returns a pointer to function that returns an integer and takes two integer parameters like Mult.




  • Functions like Mult's second parameter is default So when I call Calc, Calc returns the address of Mult or Add... depending on the value of parameter of Calc thus I can pass only one argument.


But It doesn't work with pointer to function:



int Add(int x, int y = 2) { // y is default
return x + y;
}

int Mult(int x, int y = 2) { // y is default
return x * y;
}

int Div(int x, int y = 2) { // y is default
return y ? x / y : -1;
}

int Sub(int x, int y = 2) { // y is default
return x - y;
}

int Mod(int x, int y = 2) { // y is default
return y ? x % y : -1;
}

using pFn = int(*)(int, int);


pFn Calc(char c) {
switch (c) {
case '+':
return Add;
case '*':
return Mult;
case '/':
return Div;
case '-':
return Sub;
case '%':
return Mod;
}
return Mult;
}

int main(int argc, char* argv){

pFn func = Calc('%');
cout << func(7, 4) << endl; // ok
//cout << func(7) << endl; // error: Too few arguments
cout << Mult(4) << endl; // ok. the second argument is default

func = Calc('/'); // ok
cout << func(75, 12) << endl; // ok

std::cout << std::endl;
}


Above if I call Mult with a single argument it works fine because the second argument is default but calling it through the pointer func it fails. func is pointer to function that takes two integers and returns an int.










share|improve this question




















  • 2





    What is the point of Double taking an integer parameter that it doesn't use?

    – scohe001
    4 hours ago






  • 1





    Similar: Howto: c++ Function Pointer with default values

    – TrebledJ
    4 hours ago













  • @scohe001: In a real example, for example depending on the value of the parameter of Double the function returns a pointer to a function from multiple choices: e.g: switch(x){ case 1: return Mult; break; case 2: return Add;}.

    – Syfu_H
    1 hour ago


















14















I have functions Mult, Add, Div, Sub, Mod those takes two integers and returns the result of its parameters. And a function Calc that takes a character as an Operator and returns a pointer to function that returns an integer and takes two integer parameters like Mult.




  • Functions like Mult's second parameter is default So when I call Calc, Calc returns the address of Mult or Add... depending on the value of parameter of Calc thus I can pass only one argument.


But It doesn't work with pointer to function:



int Add(int x, int y = 2) { // y is default
return x + y;
}

int Mult(int x, int y = 2) { // y is default
return x * y;
}

int Div(int x, int y = 2) { // y is default
return y ? x / y : -1;
}

int Sub(int x, int y = 2) { // y is default
return x - y;
}

int Mod(int x, int y = 2) { // y is default
return y ? x % y : -1;
}

using pFn = int(*)(int, int);


pFn Calc(char c) {
switch (c) {
case '+':
return Add;
case '*':
return Mult;
case '/':
return Div;
case '-':
return Sub;
case '%':
return Mod;
}
return Mult;
}

int main(int argc, char* argv){

pFn func = Calc('%');
cout << func(7, 4) << endl; // ok
//cout << func(7) << endl; // error: Too few arguments
cout << Mult(4) << endl; // ok. the second argument is default

func = Calc('/'); // ok
cout << func(75, 12) << endl; // ok

std::cout << std::endl;
}


Above if I call Mult with a single argument it works fine because the second argument is default but calling it through the pointer func it fails. func is pointer to function that takes two integers and returns an int.










share|improve this question




















  • 2





    What is the point of Double taking an integer parameter that it doesn't use?

    – scohe001
    4 hours ago






  • 1





    Similar: Howto: c++ Function Pointer with default values

    – TrebledJ
    4 hours ago













  • @scohe001: In a real example, for example depending on the value of the parameter of Double the function returns a pointer to a function from multiple choices: e.g: switch(x){ case 1: return Mult; break; case 2: return Add;}.

    – Syfu_H
    1 hour ago














14












14








14


4






I have functions Mult, Add, Div, Sub, Mod those takes two integers and returns the result of its parameters. And a function Calc that takes a character as an Operator and returns a pointer to function that returns an integer and takes two integer parameters like Mult.




  • Functions like Mult's second parameter is default So when I call Calc, Calc returns the address of Mult or Add... depending on the value of parameter of Calc thus I can pass only one argument.


But It doesn't work with pointer to function:



int Add(int x, int y = 2) { // y is default
return x + y;
}

int Mult(int x, int y = 2) { // y is default
return x * y;
}

int Div(int x, int y = 2) { // y is default
return y ? x / y : -1;
}

int Sub(int x, int y = 2) { // y is default
return x - y;
}

int Mod(int x, int y = 2) { // y is default
return y ? x % y : -1;
}

using pFn = int(*)(int, int);


pFn Calc(char c) {
switch (c) {
case '+':
return Add;
case '*':
return Mult;
case '/':
return Div;
case '-':
return Sub;
case '%':
return Mod;
}
return Mult;
}

int main(int argc, char* argv){

pFn func = Calc('%');
cout << func(7, 4) << endl; // ok
//cout << func(7) << endl; // error: Too few arguments
cout << Mult(4) << endl; // ok. the second argument is default

func = Calc('/'); // ok
cout << func(75, 12) << endl; // ok

std::cout << std::endl;
}


Above if I call Mult with a single argument it works fine because the second argument is default but calling it through the pointer func it fails. func is pointer to function that takes two integers and returns an int.










share|improve this question
















I have functions Mult, Add, Div, Sub, Mod those takes two integers and returns the result of its parameters. And a function Calc that takes a character as an Operator and returns a pointer to function that returns an integer and takes two integer parameters like Mult.




  • Functions like Mult's second parameter is default So when I call Calc, Calc returns the address of Mult or Add... depending on the value of parameter of Calc thus I can pass only one argument.


But It doesn't work with pointer to function:



int Add(int x, int y = 2) { // y is default
return x + y;
}

int Mult(int x, int y = 2) { // y is default
return x * y;
}

int Div(int x, int y = 2) { // y is default
return y ? x / y : -1;
}

int Sub(int x, int y = 2) { // y is default
return x - y;
}

int Mod(int x, int y = 2) { // y is default
return y ? x % y : -1;
}

using pFn = int(*)(int, int);


pFn Calc(char c) {
switch (c) {
case '+':
return Add;
case '*':
return Mult;
case '/':
return Div;
case '-':
return Sub;
case '%':
return Mod;
}
return Mult;
}

int main(int argc, char* argv){

pFn func = Calc('%');
cout << func(7, 4) << endl; // ok
//cout << func(7) << endl; // error: Too few arguments
cout << Mult(4) << endl; // ok. the second argument is default

func = Calc('/'); // ok
cout << func(75, 12) << endl; // ok

std::cout << std::endl;
}


Above if I call Mult with a single argument it works fine because the second argument is default but calling it through the pointer func it fails. func is pointer to function that takes two integers and returns an int.







c++ function-pointers default-arguments






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago







Syfu_H

















asked 4 hours ago









Syfu_HSyfu_H

1907




1907








  • 2





    What is the point of Double taking an integer parameter that it doesn't use?

    – scohe001
    4 hours ago






  • 1





    Similar: Howto: c++ Function Pointer with default values

    – TrebledJ
    4 hours ago













  • @scohe001: In a real example, for example depending on the value of the parameter of Double the function returns a pointer to a function from multiple choices: e.g: switch(x){ case 1: return Mult; break; case 2: return Add;}.

    – Syfu_H
    1 hour ago














  • 2





    What is the point of Double taking an integer parameter that it doesn't use?

    – scohe001
    4 hours ago






  • 1





    Similar: Howto: c++ Function Pointer with default values

    – TrebledJ
    4 hours ago













  • @scohe001: In a real example, for example depending on the value of the parameter of Double the function returns a pointer to a function from multiple choices: e.g: switch(x){ case 1: return Mult; break; case 2: return Add;}.

    – Syfu_H
    1 hour ago








2




2





What is the point of Double taking an integer parameter that it doesn't use?

– scohe001
4 hours ago





What is the point of Double taking an integer parameter that it doesn't use?

– scohe001
4 hours ago




1




1





Similar: Howto: c++ Function Pointer with default values

– TrebledJ
4 hours ago







Similar: Howto: c++ Function Pointer with default values

– TrebledJ
4 hours ago















@scohe001: In a real example, for example depending on the value of the parameter of Double the function returns a pointer to a function from multiple choices: e.g: switch(x){ case 1: return Mult; break; case 2: return Add;}.

– Syfu_H
1 hour ago





@scohe001: In a real example, for example depending on the value of the parameter of Double the function returns a pointer to a function from multiple choices: e.g: switch(x){ case 1: return Mult; break; case 2: return Add;}.

– Syfu_H
1 hour ago












2 Answers
2






active

oldest

votes


















15














Defaulted arguments are a bit of C++ syntactic sugar; when calling the function directly with insufficient arguments, the compiler inserts the default as if the caller had passed it explicitly, so the function is still called with the full complement of arguments (Mult(4) is compiled into the same code as Mult(4, 2) in this case).



The default isn't actually part of the function type though, so you can't use the default for an indirect call; the syntactic sugar breaks down there, since as soon as you are calling through a pointer, the information about the defaults is lost.






share|improve this answer
























  • Thank you! I do really appreciate it. Also: I've edited the question. You can edit it. Now I make the function Calc decides which function to return depending on the Character argument passed in to Calc.

    – Syfu_H
    1 hour ago



















3














For the "why not" I refer you to this answer. If you want to somehow keep the ability to use a default, you need to provide something more than a function pointer, eg a lamdba will do:



auto Double() {
return (int x,int y=2){ return Mult(x,y); };
}


And by using a variadic lambda (thanks to @Artyer) you do not even have to repeat the default value:



#include <iostream>

int Mult(int x, int y = 2) { // y is default
return x * y;
}

auto Double() {
return (auto... args) { return Mult(args...); };
}

int main(int argc, char* argv){
auto func = Double();
std::cout << func(7, 4) << 'n'; // ok
std::cout << func(7) << 'n'; // ok
std::cout << Mult(4) << 'n'; // ok
}


Live demo






share|improve this answer


























  • Note that this involves repeating the default explicitly inside Double when defining the lambda, which limits the utility significantly.

    – ShadowRanger
    4 hours ago











  • @ShadowRanger yes, added a note

    – user463035818
    4 hours ago






  • 3





    To not have to repeat the defaults, just forward variadic arguments: return (auto... args) { return Mult(args...); } . Or with perfect forwarding (Which is not really necessary here because this just copies ints, but may be for other functions) return (auto&&... args) noexcept(noexcept(Mult(std::forward<decltype(args)>(args)...))) -> decltype(auto) { return Mult(std::forward<decltype(args)>(args)...); };

    – Artyer
    4 hours ago











  • @Artyer thanks. didnt post the forwarding one, because I would have to understand it first myself and for ints its not really worth the trouble

    – user463035818
    4 hours ago












Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55716044%2fhow-to-call-a-function-with-default-parameter-through-a-pointer-to-function-that%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









15














Defaulted arguments are a bit of C++ syntactic sugar; when calling the function directly with insufficient arguments, the compiler inserts the default as if the caller had passed it explicitly, so the function is still called with the full complement of arguments (Mult(4) is compiled into the same code as Mult(4, 2) in this case).



The default isn't actually part of the function type though, so you can't use the default for an indirect call; the syntactic sugar breaks down there, since as soon as you are calling through a pointer, the information about the defaults is lost.






share|improve this answer
























  • Thank you! I do really appreciate it. Also: I've edited the question. You can edit it. Now I make the function Calc decides which function to return depending on the Character argument passed in to Calc.

    – Syfu_H
    1 hour ago
















15














Defaulted arguments are a bit of C++ syntactic sugar; when calling the function directly with insufficient arguments, the compiler inserts the default as if the caller had passed it explicitly, so the function is still called with the full complement of arguments (Mult(4) is compiled into the same code as Mult(4, 2) in this case).



The default isn't actually part of the function type though, so you can't use the default for an indirect call; the syntactic sugar breaks down there, since as soon as you are calling through a pointer, the information about the defaults is lost.






share|improve this answer
























  • Thank you! I do really appreciate it. Also: I've edited the question. You can edit it. Now I make the function Calc decides which function to return depending on the Character argument passed in to Calc.

    – Syfu_H
    1 hour ago














15












15








15







Defaulted arguments are a bit of C++ syntactic sugar; when calling the function directly with insufficient arguments, the compiler inserts the default as if the caller had passed it explicitly, so the function is still called with the full complement of arguments (Mult(4) is compiled into the same code as Mult(4, 2) in this case).



The default isn't actually part of the function type though, so you can't use the default for an indirect call; the syntactic sugar breaks down there, since as soon as you are calling through a pointer, the information about the defaults is lost.






share|improve this answer













Defaulted arguments are a bit of C++ syntactic sugar; when calling the function directly with insufficient arguments, the compiler inserts the default as if the caller had passed it explicitly, so the function is still called with the full complement of arguments (Mult(4) is compiled into the same code as Mult(4, 2) in this case).



The default isn't actually part of the function type though, so you can't use the default for an indirect call; the syntactic sugar breaks down there, since as soon as you are calling through a pointer, the information about the defaults is lost.







share|improve this answer












share|improve this answer



share|improve this answer










answered 4 hours ago









ShadowRangerShadowRanger

64.2k661101




64.2k661101













  • Thank you! I do really appreciate it. Also: I've edited the question. You can edit it. Now I make the function Calc decides which function to return depending on the Character argument passed in to Calc.

    – Syfu_H
    1 hour ago



















  • Thank you! I do really appreciate it. Also: I've edited the question. You can edit it. Now I make the function Calc decides which function to return depending on the Character argument passed in to Calc.

    – Syfu_H
    1 hour ago

















Thank you! I do really appreciate it. Also: I've edited the question. You can edit it. Now I make the function Calc decides which function to return depending on the Character argument passed in to Calc.

– Syfu_H
1 hour ago





Thank you! I do really appreciate it. Also: I've edited the question. You can edit it. Now I make the function Calc decides which function to return depending on the Character argument passed in to Calc.

– Syfu_H
1 hour ago













3














For the "why not" I refer you to this answer. If you want to somehow keep the ability to use a default, you need to provide something more than a function pointer, eg a lamdba will do:



auto Double() {
return (int x,int y=2){ return Mult(x,y); };
}


And by using a variadic lambda (thanks to @Artyer) you do not even have to repeat the default value:



#include <iostream>

int Mult(int x, int y = 2) { // y is default
return x * y;
}

auto Double() {
return (auto... args) { return Mult(args...); };
}

int main(int argc, char* argv){
auto func = Double();
std::cout << func(7, 4) << 'n'; // ok
std::cout << func(7) << 'n'; // ok
std::cout << Mult(4) << 'n'; // ok
}


Live demo






share|improve this answer


























  • Note that this involves repeating the default explicitly inside Double when defining the lambda, which limits the utility significantly.

    – ShadowRanger
    4 hours ago











  • @ShadowRanger yes, added a note

    – user463035818
    4 hours ago






  • 3





    To not have to repeat the defaults, just forward variadic arguments: return (auto... args) { return Mult(args...); } . Or with perfect forwarding (Which is not really necessary here because this just copies ints, but may be for other functions) return (auto&&... args) noexcept(noexcept(Mult(std::forward<decltype(args)>(args)...))) -> decltype(auto) { return Mult(std::forward<decltype(args)>(args)...); };

    – Artyer
    4 hours ago











  • @Artyer thanks. didnt post the forwarding one, because I would have to understand it first myself and for ints its not really worth the trouble

    – user463035818
    4 hours ago
















3














For the "why not" I refer you to this answer. If you want to somehow keep the ability to use a default, you need to provide something more than a function pointer, eg a lamdba will do:



auto Double() {
return (int x,int y=2){ return Mult(x,y); };
}


And by using a variadic lambda (thanks to @Artyer) you do not even have to repeat the default value:



#include <iostream>

int Mult(int x, int y = 2) { // y is default
return x * y;
}

auto Double() {
return (auto... args) { return Mult(args...); };
}

int main(int argc, char* argv){
auto func = Double();
std::cout << func(7, 4) << 'n'; // ok
std::cout << func(7) << 'n'; // ok
std::cout << Mult(4) << 'n'; // ok
}


Live demo






share|improve this answer


























  • Note that this involves repeating the default explicitly inside Double when defining the lambda, which limits the utility significantly.

    – ShadowRanger
    4 hours ago











  • @ShadowRanger yes, added a note

    – user463035818
    4 hours ago






  • 3





    To not have to repeat the defaults, just forward variadic arguments: return (auto... args) { return Mult(args...); } . Or with perfect forwarding (Which is not really necessary here because this just copies ints, but may be for other functions) return (auto&&... args) noexcept(noexcept(Mult(std::forward<decltype(args)>(args)...))) -> decltype(auto) { return Mult(std::forward<decltype(args)>(args)...); };

    – Artyer
    4 hours ago











  • @Artyer thanks. didnt post the forwarding one, because I would have to understand it first myself and for ints its not really worth the trouble

    – user463035818
    4 hours ago














3












3








3







For the "why not" I refer you to this answer. If you want to somehow keep the ability to use a default, you need to provide something more than a function pointer, eg a lamdba will do:



auto Double() {
return (int x,int y=2){ return Mult(x,y); };
}


And by using a variadic lambda (thanks to @Artyer) you do not even have to repeat the default value:



#include <iostream>

int Mult(int x, int y = 2) { // y is default
return x * y;
}

auto Double() {
return (auto... args) { return Mult(args...); };
}

int main(int argc, char* argv){
auto func = Double();
std::cout << func(7, 4) << 'n'; // ok
std::cout << func(7) << 'n'; // ok
std::cout << Mult(4) << 'n'; // ok
}


Live demo






share|improve this answer















For the "why not" I refer you to this answer. If you want to somehow keep the ability to use a default, you need to provide something more than a function pointer, eg a lamdba will do:



auto Double() {
return (int x,int y=2){ return Mult(x,y); };
}


And by using a variadic lambda (thanks to @Artyer) you do not even have to repeat the default value:



#include <iostream>

int Mult(int x, int y = 2) { // y is default
return x * y;
}

auto Double() {
return (auto... args) { return Mult(args...); };
}

int main(int argc, char* argv){
auto func = Double();
std::cout << func(7, 4) << 'n'; // ok
std::cout << func(7) << 'n'; // ok
std::cout << Mult(4) << 'n'; // ok
}


Live demo







share|improve this answer














share|improve this answer



share|improve this answer








edited 4 hours ago

























answered 4 hours ago









user463035818user463035818

19.3k42971




19.3k42971













  • Note that this involves repeating the default explicitly inside Double when defining the lambda, which limits the utility significantly.

    – ShadowRanger
    4 hours ago











  • @ShadowRanger yes, added a note

    – user463035818
    4 hours ago






  • 3





    To not have to repeat the defaults, just forward variadic arguments: return (auto... args) { return Mult(args...); } . Or with perfect forwarding (Which is not really necessary here because this just copies ints, but may be for other functions) return (auto&&... args) noexcept(noexcept(Mult(std::forward<decltype(args)>(args)...))) -> decltype(auto) { return Mult(std::forward<decltype(args)>(args)...); };

    – Artyer
    4 hours ago











  • @Artyer thanks. didnt post the forwarding one, because I would have to understand it first myself and for ints its not really worth the trouble

    – user463035818
    4 hours ago



















  • Note that this involves repeating the default explicitly inside Double when defining the lambda, which limits the utility significantly.

    – ShadowRanger
    4 hours ago











  • @ShadowRanger yes, added a note

    – user463035818
    4 hours ago






  • 3





    To not have to repeat the defaults, just forward variadic arguments: return (auto... args) { return Mult(args...); } . Or with perfect forwarding (Which is not really necessary here because this just copies ints, but may be for other functions) return (auto&&... args) noexcept(noexcept(Mult(std::forward<decltype(args)>(args)...))) -> decltype(auto) { return Mult(std::forward<decltype(args)>(args)...); };

    – Artyer
    4 hours ago











  • @Artyer thanks. didnt post the forwarding one, because I would have to understand it first myself and for ints its not really worth the trouble

    – user463035818
    4 hours ago

















Note that this involves repeating the default explicitly inside Double when defining the lambda, which limits the utility significantly.

– ShadowRanger
4 hours ago





Note that this involves repeating the default explicitly inside Double when defining the lambda, which limits the utility significantly.

– ShadowRanger
4 hours ago













@ShadowRanger yes, added a note

– user463035818
4 hours ago





@ShadowRanger yes, added a note

– user463035818
4 hours ago




3




3





To not have to repeat the defaults, just forward variadic arguments: return (auto... args) { return Mult(args...); } . Or with perfect forwarding (Which is not really necessary here because this just copies ints, but may be for other functions) return (auto&&... args) noexcept(noexcept(Mult(std::forward<decltype(args)>(args)...))) -> decltype(auto) { return Mult(std::forward<decltype(args)>(args)...); };

– Artyer
4 hours ago





To not have to repeat the defaults, just forward variadic arguments: return (auto... args) { return Mult(args...); } . Or with perfect forwarding (Which is not really necessary here because this just copies ints, but may be for other functions) return (auto&&... args) noexcept(noexcept(Mult(std::forward<decltype(args)>(args)...))) -> decltype(auto) { return Mult(std::forward<decltype(args)>(args)...); };

– Artyer
4 hours ago













@Artyer thanks. didnt post the forwarding one, because I would have to understand it first myself and for ints its not really worth the trouble

– user463035818
4 hours ago





@Artyer thanks. didnt post the forwarding one, because I would have to understand it first myself and for ints its not really worth the trouble

– user463035818
4 hours ago


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55716044%2fhow-to-call-a-function-with-default-parameter-through-a-pointer-to-function-that%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

香粉寮

GameSpot