Suppose there is such a pseudocode in c ++. Some function (let's say sorting) takes some values ​​and a comparator function. Function argument values ​​can be initialized by default. Is it possible to do something like this with a comparator, just by initializing it with a lambda? This is convenient, for example, if standard types are sorted for which a comparison operation is already defined.

template<class T, class BinaryFunc> T testFunc(T t1, T t2, BinaryFunc func = [](T v1, T v2){return v1 < v2;}){ return func(t1,t2); } 

And the second question: is the auto keyword only defined for standard types? Or for custom too?
PS: you can, of course, override this fukntion, but it seems to me that it would be more concise

    1 answer 1

    Formally, lambda expressions can be used as default arguments. However, the default arguments will not be taken into account in the deduction process of the template arguments. This means that, in fact, the BinaryFunc type BinaryFunc not be deduced even with the successfully deduced type T That is, the "natural" syntax of a function call will not work.

     int a = 5, b = 10; testFunc(a, b); // Ошибка - невозможно дедуцировать тип `BinaryFunc` 

    You cannot specify the exact type of this argument explicitly manually, because the type of lambda expression is unknown to you. You can specify std::function<int(int, int)> as the type of BinaryFunc and it will work

     int a = 5, b = 10; testFunc<int, std::function<int(int, int)>>(a, b); 

    but in such a situation, the need for an independent template parameterization for this parameter generally disappears. Those. you can just do it

     template<class T> T testFunc(T t1, T t2, std::function<T(T, T)> func = [](T v1, T v2){return v1 < v2;}) { return func(t1, t2); } 

    and forget about the need to deduce the type of this argument. (In fact, the main purpose of std::function is precisely how to get rid of the template code parametrization. The price for this is the potential internal inefficiency of std::function .)

    Your original functionality can be "emulated" by overloading the function instead of using the default argument.

     template<class T, class BinaryFunc> T testFunc(T t1, T t2, BinaryFunc func) { return func(t1, t2); } template<class T> T testFunc(T t1, T t2) { return testFunc(t1, t2, [](T v1, T v2){return v1 < v2;}); } 
    • And what does "deduce" mean? - Maxim Petrov
    • @Maxim Petrov: So: the compiler will automatically output based on the types of the actual arguments of the function at the call point. Without the deduction of the template arguments by the compiler, you would have to specify the template arguments explicitly, through <...> , as in my example above. - AnT
    • template<class T> T testFunc(T t1, T t2, std::function<int(int, int)> func = [](T v1, T v2){return v1 < v2;}) { return func(t1, t2); } template<class T> T testFunc(T t1, T t2, std::function<int(int, int)> func = [](T v1, T v2){return v1 < v2;}) { return func(t1, t2); } - Maxim Petrov
    • This option is not compiled. He writes that he cannot reserve variables v1 and v2 - Maxim Petrov
    • through CLion I launch - Maxim Petrov