具有std :: function参数的函数不接受lamba函数

时间:2015-12-28 09:26:30

标签: c++11 visual-studio-2013 lambda std-function

我试图通过在我自己的双向链接列表集合上实现std::iterator并尝试使用我自己的sort函数对其进行排序来更熟悉C ++ 11标准。 / p>

我希望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”的实例与参数匹配   list参数类型是:(LinkedList,lambda [] bool   (const std :: string&amp; a,const std :: string&amp;) - &gt; bool)

其他信息,编译也会出现以下错误:

  

错误 1错误C2784:'LinkedList&lt; _Ty&gt;排序(常量   链表&LT; _Ty&GT; &amp;,std :: function)':不能   推导出'std::function<bool(_By,_By)>'

的模板参数

更新:我知道排序算法不正确并且不会做想要的事情,我无意将其保留原样并且在声明正确后没有问题修复它

1 个答案:

答案 0 :(得分:6)

问题是_By内部使用std::function这样的std::function无法从lambda闭包中推断出来。你需要传入一个实际的std::function对象,而不是一个lambda。请记住,lambda表达式的类型是未命名的类类型(称为闭包类型),而不是 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

这样,将推断闭包类型并且一切都很好。

请注意,您根本不需要 {/ 1}} - 只有当您需要存储一个仿函数或者通过一个仿函数时才需要它运行时接口(不像模板那样的编译时)。

旁注:您的代码使用的是为编译器和标准库保留的标识符(标识符以下划线开头,后跟大写字母)。这在C ++中是不合法的,您应该在代码中避免使用这样的保留标识符。