将 lamda 与模板函数一起使用时出现错误 C2672 和 C2784
error C2672 and C2784 when using lamdas with template functions
我编写了以下函数,它在遍历 2d 向量时隐藏了循环:
template<typename ElementType>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
std::function<void(ElementType & element)> function)
{
for(auto & row : vec)
{
for(auto & element : row)
{
function(element);
}
}
}
但我收到错误:
'function': no matching overloaded function found
和
'declaration' : could not deduce template argument for 'type' from 'type'
像这样与 lambda 一起使用时:
iterateOver2DVector(graph, [](Node & node) { node.update(); } );
有人知道我做错了什么吗?
该调用将尝试从第一对和第二对 parameter/argument 中推断出 ElementType
。
第二对将失败,因为函数的第二个参数不是 std::function
,而是闭包类型。
如果一对失败,则整个推导失败,即使另一对会正确推导 ElementType
的模板参数。
您的函数不需要从第二对 parameter/argument 推导出 ElementType
,因此您可以将其设为 non-deduced 上下文 , 因此不会尝试扣除它。
一个常见的方法是使用 std::type_identity_t
:
template<typename ElementType>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
std::type_identity_t<std::function<void(ElementType & element)>> function)
std::type_identity_t<T>
是 std::type_identity<T>::type
的别名,std::type_identity<T>::type
是 T
的别名,但是由于类型 T
现在是 ::
的左边处于 non-deduced 上下文中。
std::type_identity_t
仅在 C++20 之后可用,但可以在以前的 C++ 版本中轻松定义:
template<typename T> struct type_identity { using type = T; };
template<typename T> using type_identity_t = typename type_identity<T>::type;
但是,在这种情况下,std::function
只是不必要的开销。直接接受闭包类型,而不是 std::function
:
template<typename ElementType, typename F>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
F function)
A std::function
仅在您打算存储可调用对象而不依赖其特定类型时才有用,例如在 class 成员中,即使在这种情况下,也可以在分配给成员时转换为 std::function
。
我编写了以下函数,它在遍历 2d 向量时隐藏了循环:
template<typename ElementType>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
std::function<void(ElementType & element)> function)
{
for(auto & row : vec)
{
for(auto & element : row)
{
function(element);
}
}
}
但我收到错误:
'function': no matching overloaded function found
和
'declaration' : could not deduce template argument for 'type' from 'type'
像这样与 lambda 一起使用时:
iterateOver2DVector(graph, [](Node & node) { node.update(); } );
有人知道我做错了什么吗?
该调用将尝试从第一对和第二对 parameter/argument 中推断出 ElementType
。
第二对将失败,因为函数的第二个参数不是 std::function
,而是闭包类型。
如果一对失败,则整个推导失败,即使另一对会正确推导 ElementType
的模板参数。
您的函数不需要从第二对 parameter/argument 推导出 ElementType
,因此您可以将其设为 non-deduced 上下文 , 因此不会尝试扣除它。
一个常见的方法是使用 std::type_identity_t
:
template<typename ElementType>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
std::type_identity_t<std::function<void(ElementType & element)>> function)
std::type_identity_t<T>
是 std::type_identity<T>::type
的别名,std::type_identity<T>::type
是 T
的别名,但是由于类型 T
现在是 ::
的左边处于 non-deduced 上下文中。
std::type_identity_t
仅在 C++20 之后可用,但可以在以前的 C++ 版本中轻松定义:
template<typename T> struct type_identity { using type = T; };
template<typename T> using type_identity_t = typename type_identity<T>::type;
但是,在这种情况下,std::function
只是不必要的开销。直接接受闭包类型,而不是 std::function
:
template<typename ElementType, typename F>
void iterateOver2DVector(std::vector<std::vector<ElementType>> & vec,
F function)
A std::function
仅在您打算存储可调用对象而不依赖其特定类型时才有用,例如在 class 成员中,即使在这种情况下,也可以在分配给成员时转换为 std::function
。