Lambda 클로저 lvalue는 rvalue 참조 매개 변수로 전달 될 수 있습니다.


18

lvalue람다 클로저는 항상 rvalue함수 매개 변수 로 전달 될 수 있다는 것을 알았습니다 .

다음의 간단한 데모를 참조하십시오.

#include <iostream>
#include <functional>

using namespace std;

void foo(std::function<void()>&& t)
{
}

int main()
{
    // Case 1: passing a `lvalue` closure
    auto fn1 = []{};
    foo(fn1);                          // works

    // Case 2: passing a `lvalue` function object
    std::function<void()> fn2 = []{};
    foo(fn2);                          // compile error

    return 0;
}

사례 2는 표준 동작입니다 (방금 std::function데모 목적으로 사용 했지만 다른 유형은 동일하게 작동합니다).

사례 1은 어떻게, 왜 작동합니까? fn1함수가 반환 된 후 클로저 상태는 무엇입니까 ?


5
fn1내재적으로 std::functionin 로 변환 되기 때문 입니다 foo(fn1). 그런 임시 함수는 rvalue입니다.
eike

@RichardCritten 정말 확실하지 않아서 답변을 게시하지 않았습니다. 나는 이제 다른 것을 필요로하지 않는다고 생각한다.
eike

1
@eike np 나는 종종 같은 방식으로 느끼고 많은 답변을 얻습니다.
Richard Critten

2
@Sumudu 질문을 한 사람은 그들이 무엇을 물어 보는지 몰랐기 때문에 당신을 잘못 인도했습니다. 그들이 묻는 것은 "왜 std::function람다에서 추론의 주장을 추론 할 수 없는가 "였다. 프로그램이의 템플릿 인수를 추론하지 않으므로 std::function암시 적 변환에는 문제가 없습니다.
eerorika

1
연결 한 질문의 제목이 약간 잘못되었습니다. std::function람다 클로저를 허용하는 비명 시적 생성자가 있으므로 암시 적 변환이 있습니다. 그러나 연결된 질문의 상황 std::function에서 람다 유형에서 템플릿 인스턴스화를 유추 할 수 없습니다. (예를 들어 , 무효가 아닌 반환 유형이 있어도 std::function<void()>구성 할 수 있습니다 [](){return 5;}.
eike

답변:


8

사례 1은 어떻게, 왜 작동합니까?

호출 foo하려면 rvalue 참조에std::function<void()> 바인딩 된 인스턴스가 필요합니다 . 서명 과 호환되는 호출 가능한 객체 로 구성 할 수 있습니다 .std::function<void()>void()

먼저 임시 std::function<void()>객체는로 구성됩니다 []{}. 사용 된 생성자는 # 5 here 로 클로저를 std::function인스턴스에 복사합니다 .

template< class F >
function( F f );

로 대상을 초기화합니다 std::move(f). 경우 f회원에게 기능 또는 널 포인터에 NULL 포인터가, *this호출 후 비어 있습니다.

그런 다음 임시 function인스턴스는 rvalue 참조에 바인딩됩니다.


함수가 반환 된 후 fn1 클로저 상태는 무엇입니까?

std::function인스턴스 로 복사되었으므로 이전과 동일 합니다. 원래 폐쇄는 영향을받지 않습니다.


8

람다는가 아닙니다 std::function. 참조는 직접 바인딩되지 않습니다 .

람다는 std::functions 로 변환 가능하기 때문에 사례 1이 작동합니다 . 이것은 복사 로 임시 std::function가 구체화 됨을 의미합니다 . 이 임시는 rvalue 참조에 바인딩 될 수 있으므로 인수가 매개 변수와 일치합니다. fn1

그리고 복사는 또한 fn1에서 발생하는 모든 것에 영향을받지 않는 이유 입니다 foo.


5

함수가 반환 된 후 fn1 클로저 상태는 무엇입니까?

fn1 아무것도 캡처하지 않기 때문에 상태가 없습니다.

사례 1은 어떻게, 왜 작동합니까?

인수가 rvalue 참조 된 유형과 다른 유형이기 때문에 작동합니다. 유형이 다르기 때문에 암시 적 변환이 고려됩니다. 람다는이 인수에 대해 호출 가능하므로의 std::function템플릿 변환 생성자를 통해 암시 적으로 변환 할 수 std::function있습니다. 변환 결과는 prvalue이므로 rvalue 참조와 바인딩 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.