为什么无法将lambda作为C++函数参数的默认值使用?
问题原因
你遇到的编译错误是C++模板实参推导的标准规则导致的,核心原因有两点:
- 代码中
auto comparison是C++20引入的缩写函数模板语法,这行参数声明等价于隐式定义了一个额外的模板形参,你的函数完整模板签名等价于:template<typename T, typename Comp> decltype(auto) find_median(T begin, T end, bool sorted = false, Comp comparison = [](auto a, auto b){return a < b;}) - C++标准明确规定:函数参数的默认值不参与模板实参推导。你调用时没有给
comparison传实参,编译器无法推导出隐式模板形参Comp的具体类型,哪怕你给comparison设了默认的lambda实参,也不会用这个默认值的类型来推导模板形参,因此直接编译失败。
这个规则和下面的代码编译失败的原理完全一致:
template<typename T> void func(T a = 10) {} func(); // 编译错误,无法推导T的类型
修复方案
- C++20及以上版本,显式给比较器对应的模板形参设置默认类型即可:
template<typename T, typename Comp = decltype([](auto a, auto b){return a < b;})> decltype(auto) find_median(T begin, T end, bool sorted = false, Comp comparison = Comp{}){ assert(begin != end); // 原nullptr判断仅对指针类迭代器有效,替换为通用迭代器判断 return sorted ? find_median_sorted(begin, end) : find_median_unsorted(begin, end, comparison); }
- 若需要兼容C++17及更早版本,可以把默认比较器换成标准库的
std::less:
template<typename T, typename Comp = std::less<>> decltype(auto) find_median(T begin, T end, bool sorted = false, Comp comparison = Comp{}){ assert(begin != end); return sorted ? find_median_sorted(begin, end) : find_median_unsorted(begin, end, comparison); }
额外注意点
原代码中assert(begin != nullptr);仅对迭代器是原生指针的场景有效,如果传入标准容器的自定义迭代器(比如std::vector<int>::iterator),和nullptr比较会直接编译报错,建议替换为begin != end的判断,符合迭代器的通用设计规范。
内容的提问来源于stack exchange,提问作者beep_boop
相关产品推荐
相关产品推荐

