如何将带有泛型参数的lambda函数作为参数传递?

时间:2017-04-18 01:34:54

标签: c++ c++11 generics lambda

我无法理解如何将lambda与泛型参数一起使用,并将其作为参数传递给另一种方法。
我现在的代码下面(当然是错的):

class Arrays final
{
public:    
    template<class RandomIt>
    static void InsertionSort(RandomIt first, RandomIt last) {
        auto func = [](RandomIt lt, RandomIt rt) {
            return *lt > (*rt);
        };
        InsertSort(first, last, func);
    }

    template<class RandomIt>
    static void InsertionSortDesc(RandomIt first, RandomIt last) {
        auto func = [](RandomIt lt, RandomIt rt) {
            return *lt < (*rt);
        };
        InsertSort(first, last, func);
    }

private:
    Arrays();

    template<class RandomIt>
    static void InsertSort(RandomIt first, RandomIt last,
                         std::function<bool (RandomIt, RandomIt)> func) {
        int length = std::distance(first, last);

        if (length < 2) {
            return;
        }

        RandomIt j = first + 1;

        for (; j != last; ++j) {
            auto key = *j;
            RandomIt i = j - 1;

            while (i >= first && func(i, j)) {
                *(i + 1) = (*i);
                --i;
            }

            *(++i) = key;
        }
    }
};

它在编译时遇到错误崩溃:

arrays.h:38: error: no matching function for call to 'Arrays::InsertSort(const int*&, const int*&, Arrays::InsertionSort(RandomIt, RandomIt) [with RandomIt = const int*]::<lambda(const int*, const int*)>&)'
         InsertSort(first, last, func);
                   ^

如何正确编写?是否可以在C ++ v11中使用?

1 个答案:

答案 0 :(得分:2)

注意:我没有测试过您的代码。但是,以下编译。该函数是静态的,因此其声明必须按使用顺序排列。要修复它,请在使用它的所有其他函数之前移动InsertSort的声明。接下来,您需要使用模板参数调用InsertSort

前:

#include <iostream>
#include <vector>

class Arrays final
{
private:
    Arrays();

    template<class RandomIt>
    static void InsertSort(RandomIt first, RandomIt last,
                           std::function<bool (RandomIt, RandomIt)> func) {
        auto length = std::distance(first, last);

        if (length < 2) {
            return;
        }

        RandomIt j = first + 1;


        for (; j != last; ++j) {
            auto key = *j;
            RandomIt i = j - 1;

            while (i >= first && func(i, j)) {
                *(i + 1) = (*i);
                --i;
            }

            *(++i) = key;
        }
    }

public:
    template<class RandomIt>
    static void InsertionSort(RandomIt first, RandomIt last) {
        auto func = [](RandomIt lt, RandomIt rt) {
            return *lt > (*rt);
        };
        InsertSort<RandomIt>(first, last, func);
    }

    template<class RandomIt>
    static void InsertionSortDesc(RandomIt first, RandomIt last) {
        auto func = [](RandomIt lt, RandomIt rt) {
            return *lt < (*rt);
        };
        InsertSort<RandomIt>(first, last, func);
    }
};

int main(int argc, const char * argv[]) {

    std::vector<int> vec = {1, 9, 4, 5, 2, 3, 8, 6, 7};

    Arrays::InsertionSort(vec.begin(), vec.end());


    for (auto i : vec) {
        std::cout<<i<<" ";
    }

    std::cout<<std::endl;

    return 0;
}

如评论中所述:D如果您有资格调用该函数,则不必更改声明顺序。

例如:Arrays::InsertSort<RandomIt>(....);

class Arrays final
{
public:
    template<class RandomIt>
    static void InsertionSort(RandomIt first, RandomIt last) {
        auto func = [](RandomIt lt, RandomIt rt) {
            return *lt > (*rt);
        };
        Arrays::InsertSort<RandomIt>(first, last, func);
    }

    template<class RandomIt>
    static void InsertionSortDesc(RandomIt first, RandomIt last) {
        auto func = [](RandomIt lt, RandomIt rt) {
            return *lt < (*rt);
        };
        Arrays::InsertSort<RandomIt>(first, last, func);
    }

private:
    Arrays();

    template<class RandomIt>
    static void InsertSort(RandomIt first, RandomIt last,
                           std::function<bool (RandomIt, RandomIt)> func) {
        auto length = std::distance(first, last);

        if (length < 2) {
            return;
        }

        RandomIt j = first + 1;

        for (; j != last; ++j) {
            auto key = *j;
            RandomIt i = j - 1;

            while (i >= first && func(i, j)) {
                *(i + 1) = (*i);
                --i;
            }

            *(++i) = key;
        }
    }
};