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
함수가 반환 된 후 클로저 상태는 무엇입니까 ?
답변
사례 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
인스턴스 로 복사되었으므로 이전과 동일 합니다. 원래 폐쇄는 영향을받지 않습니다.
답변
람다는가 아닙니다 std::function
. 참조는 직접 바인딩되지 않습니다 .
람다는 std::function
s 로 변환 가능하기 때문에 사례 1이 작동합니다 . 이것은 복사 로 임시 std::function
가 구체화 됨을 의미합니다 . 이 임시는 rvalue 참조에 바인딩 될 수 있으므로 인수가 매개 변수와 일치합니다. fn1
그리고 복사는 또한 fn1
에서 발생하는 모든 것에 영향을받지 않는 이유 입니다 foo
.
답변
함수가 반환 된 후 fn1 클로저 상태는 무엇입니까?
fn1
아무것도 캡처하지 않기 때문에 상태가 없습니다.
사례 1은 어떻게, 왜 작동합니까?
인수가 rvalue 참조 된 유형과 다른 유형이기 때문에 작동합니다. 유형이 다르기 때문에 암시 적 변환이 고려됩니다. 람다는이 인수에 대해 호출 가능하므로의 std::function
템플릿 변환 생성자를 통해 암시 적으로 변환 할 수 std::function
있습니다. 변환 결과는 prvalue이므로 rvalue 참조와 바인딩 될 수 있습니다.