Open
Description
Title: Can't capture function object for UFCS.
Description:
As an exercise, I tried implementing the CL combinators from Function Composition in Programming Languages - Conor Hoekstra - CppNorth 2023.
Implementations
At first, I tried using UFCS.
That doesn't work because the capture is the postfix-expression before the $
.
That includes the object argument.
But I just wanted the function object.
Minimal reproducer (https://cpp2.godbolt.org/z/cYcb4c5YW):
w: (f) :(x) x.f$();
// w: (f) :(x) f$(x);
main: () = {
assert(w(:(x) -x;)(1) == -1);
}
Commands:
cppfront main.cpp2
clang++18 -std=c++23 -stdlib=libc++ -lc++abi -pedantic-errors -Wall -Wextra -Wconversion -Werror=unused-result -I . main.cpp
Expected result: Same as not using UFCS.
Actual result and error:
Cpp2 lowered to Cpp1:
//=== Cpp2 type declarations ====================================================
#include "cpp2util.h"
//=== Cpp2 type definitions and function declarations ===========================
[[nodiscard]] auto w(auto const& f) -> auto;
// w: (f) :(x) f$(x);
auto main() -> int;
//=== Cpp2 function definitions =================================================
[[nodiscard]] auto w(auto const& f) -> auto { return [_0 = x.f](auto const& x) -> auto { return _0(); }; }
auto main() -> int{
cpp2::Default.expects(w([](auto const& x) -> auto { return -x; })(1) == -1, "");
}
Output:
build/main.cpp:19:60: error: use of undeclared identifier 'x'
19 | [[nodiscard]] auto w(auto const& f) -> auto { return [_0 = x.f](auto const& x) -> auto { return _0(); }; }
| ^
build/main.cpp:19:97: error: use of undeclared identifier '_0'
19 | [[nodiscard]] auto w(auto const& f) -> auto { return [_0 = x.f](auto const& x) -> auto { return _0(); }; }
| ^
build/main.cpp:19:77: warning: unused parameter 'x' [-Wunused-parameter]
19 | [[nodiscard]] auto w(auto const& f) -> auto { return [_0 = x.f](auto const& x) -> auto { return _0(); }; }
| ^
build/main.cpp:19:34: warning: unused parameter 'f' [-Wunused-parameter]
19 | [[nodiscard]] auto w(auto const& f) -> auto { return [_0 = x.f](auto const& x) -> auto { return _0(); }; }
| ^
2 warnings and 2 errors generated.