0

How is it possible to use a templated functions with the STL provided algorithms in <algorithm>? For example, this code does not compile because compiler can't deduce template parameters for the predicate function:

#include <iostream>
#include <algorithm>

template< typename CharType >
bool predicate( const CharType& c )
{
    return c == '0';
}

std::string
process_string( const std::string& str )
{
    std::string result;
    std::copy_if( str.begin( ),
                  str.end( ),
                  std::back_inserter( result ),
                  predicate );
    return result;
}

int main()
{
    std::cout << process_string("AK0NNDK0ASDAS0") << std::endl;
    return 0;
}
0

5 Answers 5

6

Several ways: including

  • provide explicitly the type

    predicate<std::string::value_type>
    
  • use lambda

    [](auto&&e) { predicate(e); }
    
Sign up to request clarification or add additional context in comments.

2 Comments

auto&& is more generic, but not required in this particular case.
Unfortunately, the lambda code doesn't work in c++11, which is a tag in the question. generic lambda's do work from c++14 on.
5

You can provide the type: predicate<std::string::value_type>

Comments

1

A template itself can not be a function argument. In this case you want to pass a function pointer to the template function, which you have to instantiate as predicate<char>:

std::copy_if( str.begin( ),
              str.end( ),
              std::back_inserter( result ),
              predicate<char> );

Comments

1

Use an instantiated functor w/ a templated operator():

namespace detail {

struct predicateFunctor {
    template<typename CharType>
    bool operator()(const CharType& c)
    {
        return c == '0';
    }
};

} /*namespace detail*/

static auto predicate = detail::predicateFunctor{};

std::string process_string(const std::string& str)
{
    std::string result;
    std::copy_if(str.begin(), str.end(), std::back_inserter(result), predicate);
    return result;
}


int main()
{
    std::cout << process_string("AK0NNDK0ASDAS0") << std::endl;
    return 0;
}

Demo

Comments

0

use static_cast to resolve overload issue:

std::copy_if( str.begin( ),
              str.end( ),
              std::back_inserter( result ),
              static_cast<bool (*)(const char&)>(predicate) );

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.