Home > OS >  C templates as predicates for std::find_if: auto for parameters in lambdas vs free in functions vs
C templates as predicates for std::find_if: auto for parameters in lambdas vs free in functions vs

Time:08-18

Please do help to understand why auto for parameter in equivalent lambda will build correctly, but if I will use free function with auto for parameters, or templated functions, it won't. It's something I forgot about template deduction? Or new changes in C ?

Example to run (builts on MSVS 2022 compiler):

import <string>;
import <algorithm>;

auto isAllowedHandlerSymbolLambda = [](auto const& s)
{
    if (std::isalnum(s))
        return true;

    if (s == '_')
        return true;

    return false;
};

auto isAllowedHandlerSymbolFreeFunc(auto const& s)
{
    if (std::isalnum(s))
        return true;

    if (s == '_')
        return true;

    return false;
}

template< class Symbol >
auto isAllowedHandlerSymbolTemplateFunc(Symbol const& s)
{
    if (std::isalnum(s))
        return true;

    if (s == '_')
        return true;

    return false;
}

int main()
{
    std::string str{ "Something something, thank you for your time!" };
    std::find_if_not(str.cbegin(), str.cend(), isAllowedHandlerSymbolLambda); // yes!
    //std::find_if_not(str.cbegin(), str.cend(), isAllowedHandlerSymbolFreeFunc); // no
    //std::find_if_not(str.cbegin(), str.cend(), isAllowedHandlerSymbolTemplateFunc); // nope!
}

CodePudding user response:

lambda are similar to functor class, not function:

struct lamba_unique_name
{
    template <typename T>
    auto operator()(const T& s) const { /* ...*/ }
    // ...
};
lamba_unique_name isAllowedHandlerSymbolLambda;

It is its operator which is templated, not the class, So deduction for std::find_if_not predicate is just that type.

For your template functions, you would need to specify which specialization you provide:

std::find_if_not(str.cbegin(), str.cend(), &isAllowedHandlerSymbolTemplateFunc<char>);
  • Related