Consider this code:
#include <functional>
template <typename T,typename COMP>
bool foo(T a,T b,COMP c = std::less<T>()) {
return c(a,b);
}
bool bar(int a, int b){ return a<b;}
int main(){
foo(1,2,bar); // OK
foo(1,2,std::less<int>()); // OK
foo(1,2); // error
}
The first two calls are fine, but it seems to be forbidden to let the compiler infer the type of COMP
from the default parameter:
<source>:14:5: error: no matching function for call to 'foo'
foo(1,2);
^~~
<source>:4:6: note: candidate template ignored: couldn't infer template argument 'COMP'
bool foo(T a,T b,COMP c = std::less<T>()) {
^
1 error generated.
Compiler returned: 1
Am I missing something? I dont really understand why the compiler "couldn't infer template argument 'COMP'" and I rather suspect that it is not allowed to do so.
Is it possible to infer the template argument from a default parameter? If not, why?
You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };
Can default arguments be used with the template class? Explanation: The template class can use default arguments.
Template classes and functions can make use of another kind of template parameter known as a non-type parameter. A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument.
A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)
I'd suggest doing it the way it is done in standard C++ containers like map or set. It allows to infer the type and also allows to use default argument:
template <typename T,typename COMP = std::less<T>>
bool foo(T a,T b, COMP c = COMP()) { /* As before. */ }
It is not possible to infer the type. You can manually specify a default type, too:
template <typename T,typename COMP = std::less<T>>
bool foo(T a,T b,COMP c = std::less<T>()) { /* As before. */ }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With