#include void foo(std::integral auto num = 1) { st" /> #include void foo(std::integral auto num = 1) { st" /> #include void foo(std::integral auto num = 1) { st"/>

How to assign a default argument to a concept input parameter

89 Views Asked by At

I'm trying to assign a default value to a "concept" input parameter:

#include <concepts>
#include <iostream>

void foo(std::integral auto num = 1)
{
    std::cout << "Num: " << num << std::endl;
}

int main()
{
    foo(7);
    foo(true);
    foo('&');
    //foo();  // Does not compile
    return 0;
}

But I get a compilation error when the argument is omitted:

main.cpp: In function ‘int main()’:
main.cpp:14:8: error: no matching function for call to ‘foo()’
   14 |     foo();  // Does not compile
      |     ~~~^~
main.cpp:4:6: note: candidate: ‘template  requires  integral void foo(auto:11)’
    4 | void foo(std::integral auto num = 1)
      |      ^~~
main.cpp:4:6: note:   template argument deduction/substitution failed:
main.cpp:14:8: note:   couldn’t deduce template parameter ‘auto:11’
   14 |     foo();  // Does not compile
      |     ~~~^~

If assigning a default argument to a concept is not possible, then I find it strange that the program compiles when I call 'foo' with arguments, but not without.

What am I doing wrong?

I can replace foo() with foo<int>() and it'll work, but I shouldn't have to do that.

I can also replace the definition of 'foo' with:

template<typename T = int> requires std::integral<T>
void foo(T num = 1)

And it'll once again work, but I shouldn't have to be that explicit.

1

There are 1 best solutions below

0
康桓瑋 On BEST ANSWER

The types of template parameters in functions cannot be deduced from default arguments, and there is no rule change for the concept. In this case, you still need to provide the default type for the template parameter

template<std::integral T = int>
void foo(T num = 1)
{
  std::cout << "Num: " << num << std::endl;
}