我试图通过在我自己的双向链接列表集合上实现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();
});



错误:没有函数模板“ sort”的实例与参数匹配
列表参数类型为:(LinkedList,lambda [] bool
(const std :: string&a,const std :: string&)-> bool)


其他信息,该编译还会产生以下错误:


错误1错误C2784:'LinkedList 排序(const
LinkedList &,std :: function)':无法
推导'std::function<bool(_By,_By)>'的模板参数




更新:我知道排序算法不正确,不会执行所需的操作,我无意将其保持原样,并且一旦声明正确就可以解决此问题。

最佳答案

问题是不能从lambda闭包中推断出在_By内部使用的std::function。您需要传递一个实际的std::function对象,而不是lambda对象。请记住,lambda表达式的类型是未命名的类类型(称为闭包类型),而不是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 ++中是不合法的,您应该在代码中避免使用此类保留的标识符。

关于c++11 - 具有std::function参数的函数不接受lambda函数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34490845/

10-11 23:23
查看更多