Search code examples
c++c++11templatesimplicit-conversiontemplate-argument-deduction

Simplifying std::transform for single vector


I want to write a simple function to simplify std::transform for a transformation on a single vector.

What I've got so far:

template<typename T>
void transform(std::vector<T> &vec, const std::function<T(const T &)> &fun) {
  std::transform(std::begin(vec), std::end(vec), std::begin(vec), fun);
}

Now when I want to use this function I can write, for example:

transform<int>(vec, my_function);

But I would prefer if I could just use

transform(vec, my_function);

Is there a way to adjust my code to automatically infer the type?

error:

no matching function for call to 'transform' and note: candidate template ignored:
could not match 'function<type-parameter-0-0 (const type-parameter-0-0 &)>' 
against '(lambda at [...]

Solution

  • It seems you're using lambda as the argument; lambda could be converted to std::function, but implicit conversion won't be considered in template argument deduction, that's why it fails.

    Type deduction does not consider implicit conversions (other than type adjustments listed above): that's the job for overload resolution, which happens later.

    You can use static_cast explicitly to convert the lambda to std::function when passing it, or stop using std::function. e.g.

    template<typename T, typename F>
    void transform(std::vector<T> &vec, F fun) {
      std::transform(std::begin(vec), std::end(vec), std::begin(vec), fun);
    }