-1

How can one call static_assert for each data member of any given C++ lambda?

What I'm trying to do is roll my own memcpy-able std::function and have realized that any lambdas must have trivially copyable data members. I'd like to put some assertions in place for this.

Example:

template<typename T> struct has_trivial_copy {enum {value = false};};
template<> struct has_trivial_copy<int> {enum {value = true};};

int main() {
    int i = 0;
    std::string str;

    auto lambda1 = [i] {
        // static_assert(has_trivial_copy<each data member...>::value); // okay
    };

    auto lambda2 = [i, str] {
        // static_assert(has_trivial_copy<each data member...>::value); // fail
    };
}
5
  • There is nothing built-in into C++ for that. It is up to you to call static_assert for whatever you want it to be called. Commented Oct 25, 2023 at 18:56
  • 4
    "What I'm trying to do is roll my own memcpy-able std::function and have realized that any lambdas must have trivially copyable data members.": Why do you need that? You only need to check std::is_trivially_copyable on the lambda type itself. Commented Oct 25, 2023 at 19:00
  • 1
    You cannot implement std::is_trivially_copyable in user C++ by the way. That requires magic compiler support. And having a trivial copy operation is not the same as being trivially copyable, which is what is required for memcpy. Commented Oct 25, 2023 at 19:02
  • 2
    if std::is_trivially_copyable_v<decltype(lambda2)> is true then the lambda does not have members that are not trivially copyable Commented Oct 25, 2023 at 19:03
  • Thanks, I didn't know about std::is_trivially_copyable. Commented Oct 25, 2023 at 19:46

1 Answer 1

0

While it's not possible to call static_assert for every member of a lambda, it is possible to use std::is_trivially_copyable on any given lambda to assert that it is trivially copyable.

I've added the following static_assert to my custom std::function and it works nicely to show me all the places where I'm using non-trivially copyable data members in lambdas:

template <typename Functor, typename ReturnType, typename... Args>
struct FunctorHolder
{
    FunctorHolder (Functor func) : f (func)
    {
        static_assert(std::is_trivially_copyable<Functor>::value);
    }

    Functor f;
};
Sign up to request clarification or add additional context in comments.

2 Comments

There is a difference between the type itself being trivially-copyable and all of its static members being trivially-copyable. In particular, it is up to the compiler to decide whether any given lambda is trivially-copyable, see eel.is/c++draft/expr.prim.lambda#closure-3.2. But since you intent to memcpy the lambda, not its members, checking the property of the lambda is the only correct thing to do anyway.
@user17732522 "...and all of its static members being ..." -> non-static members

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.