sort test templated function lambda:非法使用此类型作为表达式

时间:2021-09-04 18:53:38

There's tons of people asking this question on *, but I haven't been able to find one with the same problem I am experiencing.

有很多人在*上问这个问题,但是我找不到一个遇到同样问题的问题。

I've written some sorting routines, and I am trying to write re-usable functions for testing these routines, however, the more sorts I write the more complicated my functions are getting, almost to the point where I'd rather just copy paste the code for each sort.

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

The following are the signatures for the sort functions I am testing:

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

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())

The main difference being the default comparator for sort_quick.

主要区别是sort_quick的默认比较器。

The following are the templated functions I am trying to get to work for testing the sorts:

以下是我试图用来测试排序的模板化函数:

#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;
}

I added the second template parameter, Comp to the functions since sort_quick requires a different comparator when dealing with duplicates.

我将第二个模板参数Comp添加到函数中,因为sort_quick在处理重复项时需要不同的比较器。

The compiler is giving me: error C2275: 'std::vector<int,std::allocator<_Ty>>' : illegal use of this type as an expression Since I am taking the function (Func parameter) by lambda or function pointer (not sure about this), the functions do not know about the default values for the comparator, so i figured I needed to be explicit and pass the comparators.

编译器给我:错误C2275:'std :: vector >':非法使用此类型作为表达式因为我通过lambda或函数指针获取函数(Func参数) (不确定这一点),函数不知道比较器的默认值,所以我想我需要明确并传递比较器。 ,std>

If I don't explicitly pass the template parameters and instead call sort(orig.begin(), orig.end(), comparator); the compiler gives me: error C2197: 'void (__cdecl *)(iterator,iterator)' : too many arguments for call.

如果我没有显式传递模板参数而是调用sort(orig.begin(),orig.end(),comparator);编译器给我:错误C2197:'void(__ cdecl *)(iterator,iterator)':调用的参数太多了。

1 个解决方案

#1


You are instantiating template functions in your main() function when you call sort_test. Since the template instantiation is occurring here, all the knowledge about the template types need to be provided before passing the function pointer to the sort_test() method. This also means that you should not provide the template parameters when you call your sort() argument function, since it is already a fully instantiated function pointer.

当您调用sort_test时,您将在main()函数中实例化模板函数。由于此处发生模板实例化,因此在将函数指针传递给sort_test()方法之前,需要提供有关模板类型的所有知识。这也意味着在调用sort()参数函数时不应提供模板参数,因为它已经是一个完全实例化的函数指针。

You are doing that for the first four (your custom sort methods), but std::sort actually has overloaded methods:

您正在为前四个(您的自定义排序方法)执行此操作,但std :: sort实际上具有重载方法:

template< class RandomIt >
void sort( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

(from cppreference.com)

The compiler is choosing the first method to instantiate since you only provide the definition of the function with one template parameter (<iterator>). You must provide both template parameters to std::sort(...) when defining the function you are passing to sort_test:

编译器选择第一种实例化方法,因为您只使用一个模板参数( )提供函数的定义。在定义要传递给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;
}

#1


You are instantiating template functions in your main() function when you call sort_test. Since the template instantiation is occurring here, all the knowledge about the template types need to be provided before passing the function pointer to the sort_test() method. This also means that you should not provide the template parameters when you call your sort() argument function, since it is already a fully instantiated function pointer.

当您调用sort_test时,您将在main()函数中实例化模板函数。由于此处发生模板实例化,因此在将函数指针传递给sort_test()方法之前,需要提供有关模板类型的所有知识。这也意味着在调用sort()参数函数时不应提供模板参数,因为它已经是一个完全实例化的函数指针。

You are doing that for the first four (your custom sort methods), but std::sort actually has overloaded methods:

您正在为前四个(您的自定义排序方法)执行此操作,但std :: sort实际上具有重载方法:

template< class RandomIt >
void sort( RandomIt first, RandomIt last );

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

(from cppreference.com)

The compiler is choosing the first method to instantiate since you only provide the definition of the function with one template parameter (<iterator>). You must provide both template parameters to std::sort(...) when defining the function you are passing to sort_test:

编译器选择第一种实例化方法,因为您只使用一个模板参数( )提供函数的定义。在定义要传递给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;
}