Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:向std::sort提供模板比较函数_C++_Sorting_Pointers_C++03 - Fatal编程技术网

C++ C++;:向std::sort提供模板比较函数

C++ C++;:向std::sort提供模板比较函数,c++,sorting,pointers,c++03,C++,Sorting,Pointers,C++03,假设我想让std::sort根据指针指向的int的值对指向int的指针向量进行排序。忽略明显的性能问题。简单吧? 制作一个函数: bool sort_helper(const int *a, const int *b) { return *a < *b; } bool排序辅助程序(常量int*a,常量int*b) { 返回*ay;} 自动c2=进行点对象比较(&比较); std::cerr我猜你在找这样的东西: template <typename co

假设我想让std::sort根据指针指向的int的值对指向int的指针向量进行排序。忽略明显的性能问题。简单吧? 制作一个函数:

bool sort_helper(const int *a, const int *b) 
{   
    return *a < *b;
}   
bool排序辅助程序(常量int*a,常量int*b)
{   
返回*a<*b;
}   
并提供给std::sort

现在,如果我们还想对指向大型对象的指针向量做同样的事情。同样的情况也适用于:
首先我们定义一个
基本上你需要的是一个高阶函数:一个返回函数的函数

template <class T, class F>
auto make_pointee_comparison(F f) {
    return [=] (T const * l, T const * r) { return f(*l, *r); };
}
打印
10
(真-假)。注意,这是一个函数对象而不是函数指针,它在C++中更为地道。但您也可以传递函数指针:

bool compare(int x, int y) { return x > y; }

auto c2 = make_pointee_comparison<int>(&compare);
std::cerr << c2(&x, &y) << c2(&y, &x);
bool比较(intx,inty){return x>y;}
自动c2=进行点对象比较(&比较);

std::cerr我猜你在找这样的东西:

template <typename comparison_function, class iterator_type>
void t_sort(const iterator_type &begin, const iterator_type &end, comparison_function compare)
{
    using deref_type = const decltype(*begin);
    std::sort(begin, end, make_pointee_comparison<deref_type>(compare));
}
template <typename comparison_function, class iterator_type>
void sort_deref(const iterator_type &begin, const iterator_type &end, comparison_function compare) {
    std::sort(begin, end, [compare](auto *a, auto *b) { compare(*a,*b); });
}

// example usage:
sort_deref(std::begin(container), std::end(container), std::less<>());
模板
void sort\u deref(常量迭代器类型和开始,常量迭代器类型和结束,比较函数比较){
排序(开始,结束,[compare](自动*a,自动*b){compare(*a,*b);});
}
//用法示例:
排序顺序(std::begin(container)、std::end(container)、std::less());

您尝试将类型<代码>比较函数>代码>值转换为模板期望类型。

在C++中不能传递函数模板指针,您可以用<代码>操作程序()/<代码>模板创建函子(与自动参数λ非常相似):

#包括


请记住,操作员必须具有常量限定符,以便调用者能够从临时对象访问它。

谢谢!我们已经测试过了,令人惊讶的是,它确实有效!C++03是否有一个等价物?@变态啊,狗屎:-)。我们可能应该开始鼓励人们使用03标签,我想人们会认为11是默认值。好的,如果我给出一个03解决方案的草图,没有那么多细节,可以吗?当然可以。对于任何阅读的人来说,上面的第一个解决方案只是C++14及以上版本(否则推导出的返回类型将不起作用)。不要担心,除非你有什么要补充的,我认为W.t得到了03边的解决方案。但是谢谢你。你们两个都投了赞成票。实际上并没有回答这个问题,即如何使用任意比较函数对任意类型的指针进行排序,通过指针指向的元素对指针进行排序-您的解决方案假设一个模板化的比较函数,专门针对这种情况,不允许使用设计用于处理元素而不是元素指针的任意比较函数。@Demorption我的意思是-为什么要在可以轻松推断的情况下显式指定集合元素类型…谢谢,我认为这完全回答了我的问题-干杯。@Demorption这个答案不正确;它不适用于完全合法的状态函子,它们可以用作比较器。不同于,比如说,另一种回答咳嗽,它正确地做到了这一点。@Nirfiedman您也没有使用相互lambda…;)
template <class T, class F>
auto make_pointee_comparison(F f) {
    return [=] (T const * l, T const * r) { return f(*l, *r); };
}
template <class F>
struct PointeeComparisonHelper {
    PointeeComparisonHelper(F f) : m_f(f) {}

    template <class T>
    bool operator()(T const * l, T const * r) const {
        return m_f(*l, *r);
    }

    F m_f;
};

template <class F>
PointeeComparisonHelper<F> make_pointee_comparison(F f) {
    return PointeeComparisonHelper<F>(f);
}
auto c = make_pointee_comparison<int>([] (int x, int y) { return x < y; });
int x = 5;
int y = 6;
std::cerr << c(&x, &y) << c(&y, &x);
bool compare(int x, int y) { return x > y; }

auto c2 = make_pointee_comparison<int>(&compare);
std::cerr << c2(&x, &y) << c2(&y, &x);
template <typename comparison_function, class iterator_type>
void t_sort(const iterator_type &begin, const iterator_type &end, comparison_function compare)
{
    using deref_type = const decltype(*begin);
    std::sort(begin, end, make_pointee_comparison<deref_type>(compare));
}
template <typename comparison_function, class iterator_type>
void sort_deref(const iterator_type &begin, const iterator_type &end, comparison_function compare) {
    std::sort(begin, end, [compare](auto *a, auto *b) { compare(*a,*b); });
}

// example usage:
sort_deref(std::begin(container), std::end(container), std::less<>());
#include <algorithm>
#include <vector>
#include <cassert>

struct less {
    template <class T>
    bool operator()(T first, T second) const {
        return first < second;
    }
};

template <class Cmp>
struct cmp_ptr {
    Cmp cmp;

    cmp_ptr(Cmp cmp):cmp(cmp) { }
    cmp_ptr() { }

    template <class T>
    bool operator()(T first, T second) const {
        return cmp(*first, *second);
    }
};

template <class Iter, class Cmp>
bool is_sorted(Iter beg, Iter end, Cmp cmp) {
   Iter prev = beg;
   Iter next = beg;
   for (next++; next != end; prev++, next++) {
      if (cmp(*next, *prev)) {
         return false;
      }
   }
   return true;
}

int main() {
    std::vector<int*> v;
    v.push_back(new int(10));
    v.push_back(new int(1));
    v.push_back(new int(5));
    v.push_back(new int(7));
    v.push_back(new int(3));
    v.push_back(new int(2));
    std::sort(v.begin(), v.end(), cmp_ptr<less>());
    assert(::is_sorted(v.begin(), v.end(), cmp_ptr<less>()));
}