对不起,这一定是一个非常简单的问题...... 我是C ++的初学者,我正在尝试使用函数模板编写一个简单的快速排序函数。
#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.
我认为我在某种程度上错误地定义了模板...尤其是val
中的template <class iterator, class val>
部分,
请问如何让它发挥作用?
答案 0 :(得分:2)
问题是编译器无法在此处推断出您的一个模板参数:
template <class iterator, class val>
void move_to_front(iterator movethis, iterator leftend) {
val temp = *movethis; // hold the element being moved
没有val
类型的函数参数,因此编译器无法知道该类型应该是什么。但无论如何你根本不需要它。如果你有C ++ 11可用,你可以使用auto
,正如Scooby建议的那样。否则,您可以使用std::iterator_traits
从迭代器类型中获取值类型:
template <class iterator>
void move_to_front(iterator movethis, iterator leftend) {
typename std::iterator_traits<iterator>::value_type temp = *movethis;
答案 1 :(得分:1)
这可能不会直接帮助,因为您似乎是故意重新发明轮子,和/或使用此方案来测试和扩展您的模板知识,而不是解决您的代码编写要解决的确切问题。但是,如果你想要做的只是实现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,但这取决于您。请参阅live example(该示例使用C ++ 11,但该函数不需要它)。
答案 2 :(得分:0)
试试这个,假设你使用的是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
}
但是,在我看来,我觉得你对所有的迭代器过于复杂。