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

标签 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 中可能吗?

最佳答案

注意:我尚未测试您的代码。但是,以下内容可以编译。该函数是静态的,因此其声明必须按使用顺序进行。要修复此问题,请移动 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;
        }
    }
};

关于c++ - 如何传递带有泛型参数作为参数的 lambda 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43462155/

相关文章:

c++ - 对象的赋值运算符

c++ - 明确禁止具体类模板特化

generics - 如何限制 Rust 中特征的通用实现?

c++ - 我可以使用别名模板专门化一个类模板吗?

处理众所周知错误的 C++ 代码分析工具

c++ - 是否可以在声明后设置 constexpr 数组中元素的值?

c++ - 创建阻塞队列

c++ - 是否可以将 std::move 对象移出函数? (C++11)

c# - C# 泛型类型的测试分配

c# - 实现泛型类的集合