[c++] 캡처 할 수없는 람다는 표준에 따라 비어 있습니까?

템플릿 함수에서 다른 람다에서 빈 (캡처가없는) 람다를 식별하는 방법을 찾고 있습니다. 나는 현재 C ++ 17을 사용하고 있지만 C ++ 20 답변도 궁금합니다.

내 코드는 다음과 같습니다

template<typename T>
auto func(T lambda) {
    // The aguments of the lambdas are unknown

    if constexpr (/* is captureless */) {
        // do stuff
    }
}

C ++ 표준 (17 또는 20)에서 함수 포인터로 변환 할 수있는 캡처없는 람다는 수율을 보장 할 std::is_empty수 있습니까?

이 코드를 예로 들어 보겠습니다.

auto a = []{}; // captureless
auto b = [c = 'z']{}; // has captures

static_assert(sizeof(a) == sizeof(b)); // Both are the same size
static_assert(!std::is_empty_v<decltype(b)>); // It has a `c` member
static_assert(std::is_empty_v<decltype(a)>); // Passes. It is guaranteed?

라이브 예



답변

사실,이 표준은 람다가 선언과 일치하지 않는 크기를 가질 수있는 권한을 명시 적으로 부여합니다. [expr.prim.lambda.closure] / 2 개 상태

클로저 유형은 해당 람다식이 포함 된 가장 작은 블록 범위, 클래스 범위 또는 네임 스페이스 범위에서 선언됩니다. [참고 : 클로저 유형 ([basic.lookup.argdep])과 관련된 네임 스페이스 및 클래스 집합을 결정합니다. 람다 선언자의 매개 변수 유형은 이러한 관련 네임 스페이스 및 클래스에 영향을 미치지 않습니다. — 종료 참고] 클로저 유형은 집계 유형이 아닙니다. 구현은 변경에 의한 것 이외의 프로그램의 관찰 가능한 동작을 변경하지 않는 한 아래에 설명 된 것과 다르게 폐쇄 유형을 정의 할 수 있습니다.

  • 클로저 타입의 크기 및 / 또는 정렬

  • 클로저 유형이 간단하게 복사 가능한지 ([class.prop]) 또는 (2.3)

  • 클로저 유형이 표준 레이아웃 클래스인지 여부 ([class.prop])

구현시 rvalue 참조 유형의 멤버를 클로저 유형에 추가해서는 안됩니다.

강조 광산

따라서이를 통해 구현은 람다에 캡처가없는 경우에도 멤버를 제공 할 수 있습니다. 나는 어떤 구현도 가능하다고 생각하지 않지만 법적으로 그렇게 할 수 있습니다.


답변