带有 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++ 中是不合法的,您应该避免在您的代码中使用此类保留标识符。