排序测试模板化函数 lambda:非法使用此类型作为表达式

sort test templated function lambda: illegal use of this type as an expression

本文关键字:类型 表达式 非法 测试 lambda 函数 排序      更新时间:2023-10-16

有很多人在stackoverflow上问这个问题,但我找不到一个与我遇到的问题相同的问题。

我已经编写了一些排序例程,并且正在尝试编写可重用的函数来测试这些例程,但是,我编写的排序越多,我的函数就越复杂,几乎到了我宁愿复制粘贴每种排序的代码的地步。

以下是我正在测试的排序函数的签名:

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: PASSn" << 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: PASSn" << 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.

调用sort_test时,您正在main()函数中实例化模板函数。由于模板实例化发生在此处,因此在将函数指针传递给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>) 的函数定义。在定义要传递给sort_test的函数时,您必须提供两个模板参数std::sort(...)

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;
}
相关文章: