排序测试模板化函数 lambda:非法使用此类型作为表达式
sort test templated function lambda: illegal use of this type as an expression
有很多人在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;
}
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 如何计算具有指定类型的表达式的相对精度和绝对精度
- 来自 DLL 的函数调用 [表观调用的括号前面的表达式必须具有(指向-)函数类型]
- 表达式 SFINAE:如何根据类型是否包含具有一个或多个参数的函数来选择模板版本
- 有没有办法一次声明相同类型的多个对象,并通过一个表达式立即使用相同的右值初始化它们?
- 表观调用前面的表达式必须具有指向 func 类型的指针
- 数组类型 int[n][n] 不可赋值,因为表达式必须具有常量值
- 正则表达式以匹配数字的重复模式,后跟任何类型的分隔符?
- C++ 编译错误:意外的类型名称"字符串":预期的表达式
- 表达式必须具有类类型 vs.
- 错误:表达式必须具有算术、无作用域枚举或带有运算符重载的指针类型
- 非类类型表达式的静态类型与动态类型之间的差异
- 如何确定涉及 C++ 中除法的算术表达式的数据类型
- 结构化绑定初始值设定项表单 { 赋值表达式 } 对于 clang 上的数组类型失败
- 下标需要数组或指针类型表达式必须具有指针对象类型
- 带有数组类型表达式的错误分配
- 表示函数参数的元组的类型表达式
- 如何确定撤销类型表达式的更大类型
- c++ 11中有新的函数类型表达式格式吗?