递归泛型函数用作谓词,编译失败

Recursive generic function used as a predicate, compilation failure

本文关键字:编译 失败 谓词 泛型 函数 递归      更新时间:2023-10-16

我正在编写一个函数来比较两个列表的内容。元素的顺序无关紧要,所以我在比较之前对它们进行排序。列表可以是正常类型的list<int>,但也可以是列表list<list<int> >的列表。

以下是一个完整的精简示例:

#include <list>
template <typename T>
bool lessThanInAnyOrder(T lhs, T rhs)
{
  return lhs < rhs;
}
template <typename T>
bool lessThanInAnyOrder(std::list<T> lhs, std::list<T> rhs)
{
  lhs.sort(lessThanInAnyOrder<T>);
  rhs.sort(lessThanInAnyOrder<T>);
  //Do comparisons here, but for now just:
  return false;
}
int main()
{
  std::list<int> list1;
  std::list<int> list2;
  lessThanInAnyOrder(list1, list2);
}

这在GCC 4.3.3中编译,但在Visual Studio 2008中,在我调用lhs.sort():时,它会出现以下编译错误

error C2660: 'std::list<_Ty>::sort' : function does not take 1 arguments

有什么建议吗?

首先:我想如果您想比较集合,而不管它们的顺序如何,您可能正在寻找std::setset_differenceset_intersectionset_unionset_symmetric_difference算法

对于您的问题

您正在尝试按策略进行排序;如果你不能简单地专门化std::less<>,它正是为了这个目的而存在的),你可以自己制定一个自定义策略:(运行在codepad.org上的代码)

#include <list>
#include <vector>
#include <iostream>
#include <iterator>
#include <algorithm>
namespace applogic
{
    template <typename T>
    struct sort_policy
    {
        typedef std::less<T> predicate_t;
    };
    template <> struct sort_policy<std::string>
    {
        struct _Cmp { bool operator()(const std::string& a, const std::string& b) { return a.length()>b.length(); } };
        typedef _Cmp predicate_t;
    };
    template <typename C>
        void sort(C& cont)
    {
        typedef typename sort_policy<typename C::value_type>::predicate_t P;
        std::sort(cont.begin(), cont.end(), P());
    }
    template <typename T>
        void sort(std::list<T>& cont)
    {
        typedef typename sort_policy<T>::predicate_t P;
        cont.sort(P());
    }
}
template <class C>
    static void dump(const C& cont, const std::string& msg="")
{
    std::cout << msg;
    std::copy(cont.begin(), cont.end(), std::ostream_iterator<typename C::value_type>(std::cout, ", "));
    std::cout << std::endl;
}
int main()
{
    using applogic::sort;
    std::vector<int> ints;
    ints.push_back(13);
    ints.push_back(-3);
    ints.push_back(7);
    dump(ints, "before: ");
    sort(ints);
    dump(ints, "after: ");
    std::list<std::string> strings;
    strings.push_back("very very long");
    strings.push_back("tiny");
    strings.push_back("medium size");
    dump(strings, "before: ");
    sort(strings);
    dump(strings, "after: ");
    return 0;
}

编译失败,因为编译器无法选择重载的"lessThanInAnyOrder"函数传递给list::sort。您必须像这里一样明确地指定它的类型。

template <typename T>
bool lessThanInAnyOrder(std::list<T> lhs, std::list<T> rhs)
{
  bool (*comparer)(T, T) = &lessThanInAnyOrder<T>;
  lhs.sort(comparer);
  rhs.sort(comparer);
 
  //Do comparisons here, but for now just:
  return false;
}

用显式类型参数包装std::ptr_fun中的函数:

lhs.sort(std::ptr_fun<T, T>(lessThanInAnyOrder<T>));

我猜,对于int类型,您可以简单地这样写:

lhs.sort();
rhs.sort();

演示。