How to call a function with default parameters when used as non-type template parameter?

141 views Asked by At

This is a follow-up of this question: Passing function as a class's template paremeter with unknown type

My navie idea was that Jarod42s answer:

template <auto F>
class A{
public:
    void func(){
        F();
    }
};

allows to use functions with default parameters as parameter to A and call them via F(). If this was possible, the above A could handle functions of arbitrary type, given all parameters have defaults.

However this fails:

void foo(int x= 0){}
double bar(int y=0,int x=0) {return 1;}

template <auto F>
class A{
public:
    void func(){
        F();
    }
};

int main(){
    A<&foo> a;
    a.func();  
}

with error:

<source>: In instantiation of 'void A<F>::func() [with auto F = foo]':
<source>:14:12:   required from here
<source>:8:10: error: too few arguments to function
    8 |         F();
      |         ~^~
ASM generation compiler returned: 1
<source>: In instantiation of 'void A<F>::func() [with auto F = foo]':
<source>:14:12:   required from here
<source>:8:10: error: too few arguments to function
    8 |         F();
      |         ~^~
Execution build compiler returned: 1

Can the above A be fixed to call foo or bar without specializing for their exact type and use their default parameters?

1

There are 1 answers

0
463035818_is_not_an_ai On

As has been pointed out by RemyLebeau in a comment:

Default values are not part of a function's signature. Inside of your template, the default values are lost. To do what you are attempting, you will have to wrap the function calls inside of a lambda or functor

And that actually does not require to change anything about A:

int main(){
    A<[](){ return foo(); }> a;
    a.func();  
}

Live Demo