自动推断模板中的函数类型
Auto deduce type of function in template
我有简单的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
的类型?
因为id
不是一个函数。这是一个函数模板!
意思是id
是一个生成函数的模板,比如id<const int>
,但它本身并不是真正的函数。
在运行时没有 id
,只有 id
创建的函数实例。
如果您在 C++14 兼容环境中,有一种非常干净的方法可以做到这一点。不使用 std::function 和模板化 class,而是使用不受约束的转发引用和通用 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 中,您必须用其 operator() 是模板化方法的仿函数替换通用 lambda,如下所示:
struct {
template<typename T>
T operator()(T x) const
{
return x;
}
} id;
在 C++98 语法中,您将无法使用转发引用,因此您将不得不考虑复制和函子可变性问题。
我有简单的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
的类型?
因为id
不是一个函数。这是一个函数模板!
意思是id
是一个生成函数的模板,比如id<const int>
,但它本身并不是真正的函数。
在运行时没有 id
,只有 id
创建的函数实例。
如果您在 C++14 兼容环境中,有一种非常干净的方法可以做到这一点。不使用 std::function 和模板化 class,而是使用不受约束的转发引用和通用 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 中,您必须用其 operator() 是模板化方法的仿函数替换通用 lambda,如下所示:
struct {
template<typename T>
T operator()(T x) const
{
return x;
}
} id;
在 C++98 语法中,您将无法使用转发引用,因此您将不得不考虑复制和函子可变性问题。