[英]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.