Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expected to work with Lambdas? #137

Open
jonesmz opened this issue Sep 6, 2023 · 3 comments
Open

Expected to work with Lambdas? #137

jonesmz opened this issue Sep 6, 2023 · 3 comments

Comments

@jonesmz
Copy link

jonesmz commented Sep 6, 2023

Hi, I see in the Limitations section

Boost.PFR library works with types that satisfy the requirements of SimpleAggregate: aggregate types without base classes, const fields, references, or C arrays:

A casual reader may have seen on the internet "Lambdas are just syntax sugar around a struct with operator()", and expect that Boost.PFR would be able to introspect the types of the capture list of a lambda, since they are "just structs".

Sadly, this does not appear to work in Boost.PFR.

#include <boost/pfr/tuple_size.hpp>

void function()
{
    auto lambda = [](void)mutable{};
    using lambda_t = decltype(lambda);
    static_assert(0 == boost::pfr::tuple_size_v<lambda_t>);
}

This gives the error:

D:\builds\cm-systest\system\pub\dists\boost\boost/pfr/detail/fields_count.hpp(285): error C2338: static_assert failed: '====================> Boost.PFR: Type must be aggregate initializable.'
D:\builds\cm-systest\system\pub\dists\boost\boost/pfr/tuple_size.hpp(33): note: see reference to function template instantiation 'size_t boost::pfr::detail::fields_count<T>(void) noexcept' being compiled
        with
        [
            T=lambda_t
        ]

on the visual studio 2022 compiler, with similar errors on clang 16. (Both in C++17 mode, if that makes a difference).

I think it might be helpful for people searching for libraries to do introspection if you clearly document that lambdas are or are not supported in the Limitations section, with a brief explanation of why not (e.g. not aggregate types, because compiler-magic).

@schaumb
Copy link

schaumb commented Nov 22, 2023

Lambdas are not aggregate types.
See: https://eel.is/c++draft/expr.prim.lambda.closure#3

@denzor200
Copy link
Contributor

Definitely it will not work with lambdas :)
Nobody discovered such technique

@schaumb
Copy link

schaumb commented Dec 10, 2023

(These hacks are listed because if someone wants to experiment with lambdas):


It can check that it is layout compatible with a type list:

    int a;
    bool c;
    auto xx = [a, c] {};
    using type = decltype(xx);

    struct CC {
        int x;
        bool y;
    };

    static_assert(std::is_layout_compatible_v<type, CC>);

Compiler and lambda-specific member getters:
GCC uses public variables with double underscore.

int a;
auto l = [a] {};
int& lambda_a = l.__a;

MSVC uses the same named private variables :

int a;
auto l = [a] {};
// somehow get the &decltype(l)::a , ex: https://github.com/martong/access_private

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants