簡體   English   中英

使用迭代器的C ++模板函數

[英]C++ template function using iterators

抱歉,這必須是一個非常簡單的問題...我是C ++的初學者,我試圖使用函數模板編寫一個簡單的quicksort函數。

#include <iostream>
#include <vector>
using namespace std;

template <class iterator, class val>
void move_to_front(iterator movethis, iterator leftend) {
  val temp = *movethis;          // hold the element being moved
  for (iterator i = movethis; i != leftend; i--) {
    *i = *(i-1);
  }                              // all other elements shift right
  *leftend = temp;               // put it back to the front
}

template <class iterator>
void qsort(iterator begin, iterator end) {
  iterator oldbegin = begin;
  for (iterator i = begin + 1; i != end; i++) {
    if (*i <= *begin) {
      move_to_front(i, begin);
      oldbegin++;
    }
  } // move elements smaller than or equal to the first element
    // to the left of the first element.
    // oldbegin indicates the first element, so it + 1 every time an 
    // element is moved to its left. 

  qsort(begin, oldbegin);
  qsort(oldbegin, end);
}

int main(int argc, char const *argv[]) {
  int test[] = {8,7,2,4,1,4,5,4,2};
  vector<int> ar(test, test+9);
  qsort(ar.begin(), ar.end());

  for (vector<int>::iterator i = ar.begin(); i != ar.end(); i++) cout << *i;
  return 0;
}

編譯器抱怨

/Users/Larry_Li/Project Euler/foo.cpp:20:11: error: no matching function for call to 'move_to_front'
          move_to_front(i, begin);
          ^~~~~~~~~~~~~
/Users/Larry_Li/Project Euler/foo.cpp:31:7: note: in instantiation of function template specialization 'qsort<std::__1::__wrap_iter<int *> >' requested here
      qsort(ar.begin(), ar.end());
      ^
/Users/Larry_Li/Project Euler/foo.cpp:6:10: note: candidate template ignored: couldn't infer template argument 'val'
    void move_to_front(iterator movethis, iterator leftend) {
         ^
1 error generated.

我認為我以某種方式定義了模板錯誤...尤其是template <class iterator, class val>val部分,

請問如何使其工作?

問題在於,編譯器無法在此處推導您的模板參數之一:

template <class iterator, class val>
void move_to_front(iterator movethis, iterator leftend) {
    val temp = *movethis;          // hold the element being moved

沒有val類型的函數參數,因此編譯器無法知道該類型是什么。 但是您仍然不需要它。 如果您有C ++ 11,則可以按照Scooby的建議使用auto 否則,您可以使用std::iterator_traits從迭代器類型獲取值類型:

template <class iterator>
void move_to_front(iterator movethis, iterator leftend) {
    typename std::iterator_traits<iterator>::value_type temp = *movethis;

這可能無法直接幫助您,因為您似乎有意重新發明輪子,並且/或者使用此方案來測試和擴展模板知識,而不是解決編寫代碼所要解決的確切問題。 但是以防萬一,您只想實現move_to_front ,請考慮std::rotate

#include <algorithm>

template <class iterator>
void move_to_front(iterator movethis, iterator leftend) {
    std::rotate(leftend, movethis, movethis + 1);
}

您可能還想考慮更改參數的順序,使其更符合STL,但這取決於您。 查看一個實時示例 (該示例使用C ++ 11,但該函數不需要它)。

假設您正在使用C ++ 11,請嘗試以下操作:

template <class iterator>
void move_to_front(iterator movethis, iterator leftend) {
  auto temp = *movethis;          // hold the element being moved
  for (iterator i = movethis; i != leftend; i--) {
    *i = *(i-1);
  }                              // all other elements shift right
  *leftend = temp;               // put it back to the front
}

但是,我認為您認為所有迭代器都過於復雜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM