自动推断模板中的函数类型

Auto deduce type of function in template

本文关键字:函数 类型      更新时间:2023-10-16

我有简单的map实现和简单的id(身份(:

template <typename T>
T map(const T& x, std::function<decltype(x[0])(decltype(x[0]))> f) {
    T res(x.size());
    auto res_iter = begin(res);
    for (auto i(begin(x)); i < end(x); ++i) {
        *res_iter++ = f(*i);
    }
    return res;
}
template <typename T>
T id(T& x) {return x;}

当我打电话时是

vector<int> a = {1,2,3,4,5,6,7,8,9};
map(a, id<const int>);

它可以工作,但我想在没有类型规范的情况下调用它,如下所示:

map(a, id);

当我这样做时,我得到错误:

error: cannot resolve overloaded function 'id' based on conversion to type 'std::function<const int&(const int&)>'
 map(a, id);
          ^

如何解决它,为什么当错误包含正确的有界类型时,编译器无法从map的上下文中推断出id的类型?

如果您处于符合 C++14 的环境中,则有一种非常干净的方法可以执行此操作。不要使用 std::function 和模板化类,而是使用不受约束的转发引用和通用 lambda,如下所示:

#include <vector>
template <typename T,typename F>
T map(const T& x, F &&f) {
  T res(x.size());
  auto res_iter = begin(res);
  for (auto i(begin(x)); i < end(x); ++i) {
    *res_iter++ = f(*i);
  }
  return res;
}
auto id = [](auto x) { return x;};
int main()
{
  std::vector<int> v = {1, 2, 3, 4};
  auto v2 = map(v, id);
}

在 C++11 中,您必须将通用 lambda 替换为其 operator(( 是模板化方法的函子,如下所示:

struct {
  template<typename T>
  T operator()(T x) const
  {
    return x;
  }
} id;

在 C++98 语法中,您将无法使用转发引用,因此您必须考虑复制和函子可变性问题。

这是因为id不是一个函数。这是一个函数模板!

这意味着id是一个生成函数(如id<const int>(的模板,但本身并不是一个真正的函数。

运行时没有id,只有id创建的函数实例。