【问题标题】:Passing iterators to templates将迭代器传递给模板
【发布时间】:2016-03-05 20:37:59
【问题描述】:

对不起,不清楚的问题。我需要使用以下模板使用插入算法对属于自定义类的对象数组进行排序:

template<typename pointer, typename T, typename Functype>
void sort_array(pointer puntatore, T* obj, int dim, Functype pred){
    T val;
    for(int i=1; i<dim; i++){
        val=obj[i];
        for(int j=(i-1); j>=0; j--){
            if(pred(obj[j].*puntatore, val.*puntatore)){
                obj[j+1]=obj[j];
                obj[j]=val;
            }
        }
    }
}

我想知道如何编写一个更通用的模板,它可以接受任何类型的迭代器,该迭代器指向类T 的对象,而不仅仅是一个指针。在参数列表中写入T obj 会给我在赋值中的变量T val 带来麻烦,在这种情况下就像*val=obj[i]val 本身就是一个迭代器。有什么方法可以告诉模板他必须采用指向T 类对象的通用迭代器(即以同样的方式编写T* 告诉它期待一个指向T 类对象的指针)?

我如何使用此模板的示例

class Example{
   int first;
   int second;
};

template<typename pointer, typename T, typename Functype>
void sort_array(pointer puntatore, T* obj, int dim, Functype pred){
    T val;
    for(int i=1; i<dim; i++){
        val=obj[i];
        for(int j=(i-1); j>=0; j--){
            if(pred(obj[j].*puntatore, val.*puntatore)){
                obj[j+1]=obj[j];
                obj[j]=val;
            }
        }
    }
}

int main(){
    Example array[5]={{1,2},{2,4},{1,7},{5,3},{6,7}};

    //now i sort the elements in the array by their first element in a decreasing order
    sort_array(&Example::first, array, 5, [](int a, int b){return (a<b);});


}

【问题讨论】:

  • @AmiTavory 写了pointer 而不是iterator,抱歉,如果这可能会造成混淆。 puntatore 只是一个指向T 类成员的指针,我加个例子
  • 没关系。实际上用谷歌搜索了它,我猜它在意大利语中的意思是“指针”。有手指指点的照片。
  • @AmiTavory 啊哈哈抱歉!是的,这意味着意大利语中的指针

标签: c++ templates iterator


【解决方案1】:

您可以从 STL 实现中获得灵感,并提供一个接口,该接口将采用范围而不是如下所示的数组:

template<typename BidirectionalIterator, typename Predicate = 
  std::less<typename std::iterator_traits<BidirectionalIterator>::value_type>>
void
insertion_sort(BidirectionalIterator first, BidirectionalIterator last, 
  Predicate pred = {}) {
  if(first != last) {
    auto it = first; 
    while(++it != last) {
      auto it2 = it;
      while(it2 != first) {
        auto it3 = it2;
        --it3;
        if(pred(*it2, *it3)) {
          std::swap(*it2, *it3);
        } else {
          break;
        }
        --it2;
      }
    }
  }
}

Live Demo

但是请注意,您还可以为您的对象提供重载的 operator&lt;operator&gt; 以使其与标准谓词一起使用:

bool
operator<(T const &A, T const &B) {
  return A.*puntatore < B.*puntatore;
}


bool
operator>(T const &A, T const &B) {
  return A.*puntatore < B.*puntatore;
}

【讨论】:

  • @luigi 很好发现我没有考虑空范围,现在更正:)。
猜你喜欢
  • 1970-01-01
  • 2012-07-11
  • 1970-01-01
  • 2021-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-12-08
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多