gpt4 book ai didi

c++ - 将 lambda 传递给函数模板

转载 作者:太空宇宙 更新时间:2023-11-04 13:09:44 24 4
gpt4 key购买 nike

我正在学习 C++,我正在尝试实现一个二进制搜索函数,该函数可以找到谓词所包含的第一个元素。该函数的第一个参数是一个 vector ,第二个参数是一个计算给定元素的谓词的函数。二分搜索函数如下所示:

template <typename T> int binsearch(const std::vector<T> &ts, bool (*predicate)(T)) {
...
}

如果像这样使用,这会按预期工作:

bool gte(int x) {
return x >= 5;
}

int main(int argc, char** argv) {
std::vector<int> a = {1, 2, 3};
binsearch(a, gte);
return 0;
}

但是如果我使用 lambda 函数作为谓词,我会得到一个编译器错误:

search-for-a-range.cpp:20:5: error: no matching function for call to 'binsearch'
binsearch(a, [](int e) -> bool { return e >= 5; });
^~~~~~~~~
search-for-a-range.cpp:6:27: note: candidate template ignored: could not match 'bool (*)(T)' against '(lambda at
search-for-a-range.cpp:20:18)'
template <typename T> int binsearch(const std::vector<T> &ts,
^
1 error generated.

以上错误是由

产生的
binsearch(a, [](int e) -> bool { return e >= 5; });

怎么了?为什么编译器不相信我的 lambda 具有正确的类型?

最佳答案

您的函数 binsearch 将函数指针作为参数。 lambda和函数指针是不同的类型:lambda 可以被视为实现 operator() 的结构的实例。

请注意,无状态 lambda(不捕获任何变量的 lambda)可隐式转换为函数指针。由于模板替换,隐式转换在这里不起作用:

#include <iostream>

template <typename T>
void call_predicate(const T& v, void (*predicate)(T)) {
std::cout << "template" << std::endl;
predicate(v);
}

void call_predicate(const int& v, void (*predicate)(int)) {
std::cout << "overload" << std::endl;
predicate(v);
}

void foo(double v) {
std::cout << v << std::endl;
}

int main() {
// compiles and calls template function
call_predicate(42.0, foo);

// compiles and calls overload with implicit conversion
call_predicate(42, [](int v){std::cout << v << std::endl;});

// doesn't compile because template substitution fails
//call_predicate(42.0, [](double v){std::cout << v << std::endl;});

// compiles and calls template function through explicit instantiation
call_predicate<double>(42.0, [](double v){std::cout << v << std::endl;});
}

你应该让你的函数 binsearch 更通用,比如:

template <typename T, typename Predicate>
T binsearch(const std::vector<T> &ts, Predicate p) {

// usage

for(auto& t : ts)
{
if(p(t)) return t;
}

// default value if p always returned false

return T{};
}

standard algorithms library 中汲取灵感.

关于c++ - 将 lambda 传递给函数模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40467496/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com