[英]How to use templated std::function as parameter?
我想为 2D-vector 制作for_each
函数,但有一个错误:
error: no matching function for call to ‘each(std::vector<std::vector<int> >&, main()::<lambda(int&)>)’
我该如何解决?
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
template <class VarType>
void each(vector<vector<VarType>> &ve, function<void (VarType &)> action) {
for(vector<VarType> &v : ve) {
for(VarType &p : v) {
action(p);
}
}
}
int main() {
vector<vector<int>> map(5);
for(vector<int> &ve : map) {
ve.resize(4);
}
each(map, [](int &val) {
val = 1;
});
}
有几种解决方案。 我建议只为该函数使用一个单独的模板参数:
template <class VarType, class Function>
void each(vector<vector<VarType>> &ve, Function action) {
// no more worries
}
的问题是,编译器不能弄清楚VarType
在function<void (VarType&)>
从传递拉姆达。 这样做:
function<void(int&)> action = [](int &val) {
val = 1;
};
each(map, action);
也可以工作,因为这样类型 ( int&
) 是已知的。
PS 在 C++17 中你可以做std::function action = [](int &val) { val = 1; };
std::function action = [](int &val) { val = 1; };
.
虽然我认为将函数作为@DeiDei 建议的另一个模板参数是更好的解决方案,但这里有一个替代方案:
如果您希望从第一个函数参数推导出VarType
,那么您可以使第二个参数成为非推导上下文:
template <class VarType>
void each(vector<vector<VarType>> &ve,
typename type_identity<function<void (VarType &)>>::type action) {
for(vector<VarType> &v : ve) {
for(VarType &p : v) {
action(p);
}
}
}
这需要 C++20 用于std::type_identity
和#include<type_traits>
,但您可以轻松实现自己的type_identity
:
template<typename T>
struct type_identity {
using type = T;
};
这是有效的,因为留给作用域解析运算符::
都是非推导的上下文,这意味着其中的模板参数不会从此函数参数推导。 您的原始函数未能通过模板参数推导,因为无法从第二个参数推导出VarType
,因为调用中给出的第二个函数参数实际上没有类型std::function<...>
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.