有很多人在stackoverflow上问这个问题,但是我还没能找到一个遇到同样问题的人。
我已经编写了一些排序例程,并且我正在尝试编写可重用的函数来测试这些例程,但是,我写的越多,我的函数就越复杂,几乎到了我&#的地步39;而只是复制粘贴每种类型的代码。
以下是我正在测试的排序函数的签名:
template<typename FwdIterator, typename Comparator = std::less<typename std::iterator_traits<FwdIterator>::value_type>>
void sort_selection(FwdIterator beg, FwdIterator end, Comparator cmp = Comparator())
template<typename BidirIt, typename Comparator = std::less<typename std::iterator_traits<BidirIt>::value_type>>
void sort_insertion(BidirIt first, BidirIt last, Comparator cmp = Comparator())
template<typename BidirIt, typename Comparator = std::less<typename std::iterator_traits<BidirIt>::value_type>>
void sort_merge(BidirIt first, BidirIt last, Comparator cmp = Comparator())
template<typename BidirIt, typename Comparator = std::less_equal<typename std::iterator_traits<BidirIt>::value_type>>
void sort_quick(BidirIt first, BidirIt last, Comparator cmp = Comparator())
主要区别是sort_quick
的默认比较器。
以下是我试图开始测试各种类型的模板化函数:
#include <vector>
#include <cassert>
#include <memory>
#include <functional>
#include <dapps/containers/sort.hpp>
#include <boost/timer/timer.hpp>
using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::allocator;
using std::less;
using std::less_equal;
using boost::timer::auto_cpu_timer;
template<typename Func, typename Comp>
static void sort_test_uniques(const string & name, Func sort, Comp comparator)
{
vector<int> orig{ 1, 4, 5, 3, 2 }, soln{ 1, 2, 3, 4, 5 };
cout << "Testing " << name << ".\n" << "Execution time:";
{
auto_cpu_timer t;
sort<vector<int>, Comp>(orig.begin(), orig.end(), comparator);
}
assert(orig == soln);
cout << "Result: PASS\n" << endl;
}
template<typename Func, typename Comp>
static void sort_test_duplicates(const string & name, Func sort, Comp comparator)
{
vector<int> orig{ 1, 4, 5, 3, 1 }, soln{ 1, 1, 3, 4, 5 };
cout << "Testing " << name << " with duplicates.\n" << "Execution time:";
{
auto_cpu_timer t;
sort<vector<int>, Comp>(orig.begin(), orig.end(), comparator);
}
assert(orig == soln);
cout << "Result: PASS\n" << endl;
}
template<typename Func, typename Comp>
static void sort_test(const string & name, Func sort, Comp comparator)
{
sort_test_uniques(name, sort, comparator);
sort_test_duplicates(name, sort, comparator);
}
int main(int argc, const char * argv [])
{
using iterator = vector<int>::iterator;
sort_test("sort_selection", &sort_selection<iterator>, less<int>());
sort_test("sort_insertion", &sort_insertion<iterator>, less<int>());
sort_test("sort_merge", &sort_merge<iterator>, less<int>());
sort_test("sort_quick", &sort_quick<iterator>, less_equal<int>());
sort_test("std:sort", &std::sort<iterator>, less<int>());
return 0;
}
我在函数中添加了第二个模板参数Comp
,因为sort_quick在处理重复项时需要不同的比较器。
编译器给了我:error C2275: 'std::vector<int,std::allocator<_Ty>>' : illegal use of this type as an expression
由于我通过lambda或函数指针获取函数(Func参数)(对此不确定),函数不知道比较器的默认值,所以我想我需要显式并传递比较器。
如果我没有明确传递模板参数而是调用sort(orig.begin(), orig.end(), comparator);
,编译器会给我:error C2197: 'void (__cdecl *)(iterator,iterator)' : too many arguments for call
。
答案 0 :(得分:0)
当您致电main()
时,您正在sort_test
功能中实例化模板功能。由于模板实例化在此处发生,因此在将函数指针传递给sort_test()
方法之前,需要提供有关模板类型的所有知识。这也意味着在调用sort()
参数函数时不应提供模板参数,因为它已经是一个完全实例化的函数指针。
您正在为前四个(自定义排序方法)执行此操作,但std::sort
实际上有重载方法:
template< class RandomIt >
void sort( RandomIt first, RandomIt last );
template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );
(来自cppreference.com)
编译器正在选择第一种实例化方法,因为您只提供了一个模板参数(<iterator>
)的函数定义。在定义要传递给std::sort(...)
的函数时,您必须向sort_test
提供两个模板参数:
int main(int argc, const char * argv [])
{
using iterator = vector<int>::iterator;
sort_test("sort_selection", &sort_selection<iterator>, less<int>());
sort_test("sort_insertion", &sort_insertion<iterator>, less<int>());
sort_test("sort_merge", &sort_merge<iterator>, less<int>());
sort_test("sort_quick", &sort_quick<iterator>, less_equal<int>());
sort_test("std:sort", &std::sort<iterator, less<int>>, less<int>());
return 0;
}