开始使用C++11特性,碰到一些问题。以下写了一个快速排序的函数模板,划分操作的比较函数使用一个std::function<int(T,T)>的参数接收,而在main中使用函数模板接收一个lambda函数[](int a, int b) -> int {return a < b;}时报错,函数不匹配。这里该如何处理?
#include <iostream>
#include <functional>
template <typename T>
void Swap(T *a, T *b) {
T tmp = *a;
*a = *b;
*b = tmp;
}
template <typename T>
int partition(T array[], int low, int high, const std::function<int(T, T)> &cmp) {
int i = low - 1;
T x = array[high];
for (int j = low; j < high; j++) {
if (cmp(array[j], x)) {
i++;
Swap(&array[j], &array[i]);
}
}
Swap(&array[i + 1], &array[high]);
return i + 1;
}
template <typename T>
void quicksort(T array[], int low, int high, const std::function<int(T, T)> &cmp) {
if (low < high) {
int mid = partition(array, low, high, cmp);
quicksort(array, low, mid - 1, cmp);
quicksort(array, mid + 1, high, cmp);
}
}
int main() {
std::cout << "Hello, World!" << std::endl;
int arr[] {5, 3, 9, 1, 6, 2};
quicksort(arr, 0, 5, [](int a, int b) -> int {
return a < b;
});
for(auto item: arr) {
std::cout << item << " ";
}
std::cout << std::endl;
return 0;
}
报错信息:
E:\Project\DesignPattern\main.cpp: In function 'int main()':
E:\Project\DesignPattern\main.cpp:39:6: error: no matching function for call to 'quicksort(int [6], int, int, main()::<lambda(int, int)>)'
});
^
E:\Project\DesignPattern\main.cpp:26:6: note: candidate: template<class T> void quicksort(T*, int, int, const std::function<int(T, T)>&)
void quicksort(T array[], int low, int high, const std::function<int(T, T)> &cmp) {
^
E:\Project\DesignPattern\main.cpp:26:6: note: template argument deduction/substitution failed:
E:\Project\DesignPattern\main.cpp:39:6: note: 'main()::<lambda(int, int)>' is not derived from 'const std::function<int(T, T)>'
});
^
迷茫2017-04-17 15:23:10
lambda が const std::function<int(T, T)>&
に変換される前に T の型を推定することはできません。
補助クラスを追加して、最初に std::function
の型を決定してから、ラムダの暗黙的な変換を実行できます。
高洛峰2017-04-17 15:23:10
型の導出中にユーザー定義型の変換は実行されません。つまり、ラムダ式から std::function への変換は実行されません。だからここにひざまずいてください。
ここで必要なのは BinaryPredicate です。 Fn &&fn を直接書くだけです。次に、Fn に対して BinaryPredicate チェックを実行します。
または、T を
などの非推論コンテキストに変換します。 リーリーまたは
リーリー