Closed
Description
The following code, based on Barry Revzin's recursive lambda recommendations and reduced from some actual software, compiles with Clang 18.1 but fails with Clang 19.
- ❌ Clang (trunk): https://godbolt.org/z/79hKhaKx3 (Using
14f745074d05fb42f5c8a625c79bf557bb980ebb
) - ✅ Clang 18.1: https://godbolt.org/z/cvEWEsEd8
#include <utility>
template <typename F> struct recursive_lambda {
template <typename... Args> auto operator()(Args&&... args) const { return fn(*this, std::forward<Args>(args)...); }
F fn;
};
template <typename F> recursive_lambda(F) -> recursive_lambda<F>;
struct Tree { Tree *left, *right; };
int sumSize(Tree *tree) {
auto accumulate = recursive_lambda {
[&](auto& self_fn, Tree *element_node) -> int {
if (!tree) return 0;
return 1 + self_fn(tree->left) + self_fn(tree->right);
}
};
return accumulate(tree);
}
Fails with:
<source>:19:17: error: function 'operator()<Tree *&>' with deduced return type cannot be used before it is defined
19 | return 1 + self_fn(tree->left) + self_fn(tree->right);
| ^
<source>:4:80: note: in instantiation of function template specialization 'sumSize(Tree *)::(anonymous class)::operator()<const recursive_lambda<(lambda at <source>:17:9)>>' requested here
4 | template <typename... Args> auto operator()(Args&&... args) const { return fn(*this, std::forward<Args>(args)...); }
| ^
<source>:23:22: note: in instantiation of function template specialization 'recursive_lambda<(lambda at <source>:17:9)>::operator()<Tree *&>' requested here
23 | return accumulate(tree);
| ^
<source>:4:38: note: 'operator()<Tree *&>' declared here
4 | template <typename... Args> auto operator()(Args&&... args) const { return fn(*this, std::forward<Args>(args)...); }
| ^