带有 std::function 参数的函数不接受 lambda 函数
A function with a std::function parameter does not accept a lamba function
我试图通过在我自己的双向链表集合上实现 std::iterator
并尝试创建我自己的 sort
函数来对其进行排序,从而更加熟悉 C++11 标准.
我希望 sort
函数通过使 sort
接受 std::function
来接受 lamba 作为一种排序方式,但它无法编译(我不知道如何实现 move_iterator
,从而返回集合的副本而不是修改传递的副本)。
template <typename _Ty, typename _By>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, std::function<bool(_By, _By)> pred)
{
LinkedList<_Ty> tmp;
while (tmp.size() != source.size())
{
_Ty suitable;
for (auto& i : source) {
if (pred(suitable, i) == true) {
suitable = i;
}
}
tmp.push_back(suitable);
}
return tmp;
}
是我对函数的定义有误吗?如果我尝试调用该函数,则会收到编译错误。
LinkedList<std::string> strings{
"one",
"two",
"long string",
"the longest of them all"
};
auto sortedByLength = sort(strings, [](const std::string& a, const std::string& b){
return a.length() < b.length();
});
Error: no instance of function template "sort" matches the argument
list argument types are: (LinkedList, lambda []bool
(const std::string &a, const std::string &)->bool)
补充信息,编译也报如下错误:
Error 1 error C2784: 'LinkedList<_Ty> sort(const
LinkedList<_Ty> &,std::function)' : could not
deduce template argument for 'std::function<bool(_By,_By)>
'
更新: 我知道排序算法不正确,不会做我想做的事,我无意保持原样,修复它也没有问题,一旦声明正确。
问题是像这样在 std::function
内部使用的 _By
不能从 lambda 闭包中推导出来。您需要传入实际的 std::function
对象,而不是 lambda。请记住,lambda 表达式的类型是未命名的 class 类型(称为闭包类型),并且 not std::function
.
你做的有点像这样:
template <class T>
void foo(std::unique_ptr<T> p);
foo(nullptr);
在这里,也无法从参数中推导出 T
。
标准库通常是如何解决这个问题的:它不会以任何方式限制自己 std::function
,而只是将谓词的类型作为其模板参数:
template <typename _Ty, typename _Pred>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, _Pred pred)
这样就可以推导出闭包类型了,一切正常
请注意,您根本 不需要 std::function
— 这几乎只在需要 存储 时才需要仿函数,或通过运行时接口(不是像模板那样的编译时接口)传递它。
旁注:您的代码使用的标识符是为编译器和标准库保留的(标识符以下划线开头,后跟大写字母)。这在 C++ 中是不合法的,您应该避免在您的代码中使用此类保留标识符。
我试图通过在我自己的双向链表集合上实现 std::iterator
并尝试创建我自己的 sort
函数来对其进行排序,从而更加熟悉 C++11 标准.
我希望 sort
函数通过使 sort
接受 std::function
来接受 lamba 作为一种排序方式,但它无法编译(我不知道如何实现 move_iterator
,从而返回集合的副本而不是修改传递的副本)。
template <typename _Ty, typename _By>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, std::function<bool(_By, _By)> pred)
{
LinkedList<_Ty> tmp;
while (tmp.size() != source.size())
{
_Ty suitable;
for (auto& i : source) {
if (pred(suitable, i) == true) {
suitable = i;
}
}
tmp.push_back(suitable);
}
return tmp;
}
是我对函数的定义有误吗?如果我尝试调用该函数,则会收到编译错误。
LinkedList<std::string> strings{
"one",
"two",
"long string",
"the longest of them all"
};
auto sortedByLength = sort(strings, [](const std::string& a, const std::string& b){
return a.length() < b.length();
});
Error: no instance of function template "sort" matches the argument list argument types are: (LinkedList, lambda []bool (const std::string &a, const std::string &)->bool)
补充信息,编译也报如下错误:
Error 1 error C2784: 'LinkedList<_Ty> sort(const LinkedList<_Ty> &,std::function)' : could not deduce template argument for '
std::function<bool(_By,_By)>
'
更新: 我知道排序算法不正确,不会做我想做的事,我无意保持原样,修复它也没有问题,一旦声明正确。
问题是像这样在 std::function
内部使用的 _By
不能从 lambda 闭包中推导出来。您需要传入实际的 std::function
对象,而不是 lambda。请记住,lambda 表达式的类型是未命名的 class 类型(称为闭包类型),并且 not std::function
.
你做的有点像这样:
template <class T>
void foo(std::unique_ptr<T> p);
foo(nullptr);
在这里,也无法从参数中推导出 T
。
标准库通常是如何解决这个问题的:它不会以任何方式限制自己 std::function
,而只是将谓词的类型作为其模板参数:
template <typename _Ty, typename _Pred>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, _Pred pred)
这样就可以推导出闭包类型了,一切正常
请注意,您根本 不需要 std::function
— 这几乎只在需要 存储 时才需要仿函数,或通过运行时接口(不是像模板那样的编译时接口)传递它。
旁注:您的代码使用的标识符是为编译器和标准库保留的(标识符以下划线开头,后跟大写字母)。这在 C++ 中是不合法的,您应该避免在您的代码中使用此类保留标识符。