Program Tip

C ++ Lambda : "변경 가능"과 참조에 의한 캡처의 차이점

programtip 2020. 11. 18. 09:40
반응형

C ++ Lambda : "변경 가능"과 참조에 의한 캡처의 차이점


C ++에서는 다음과 같이 람다를 선언 할 수 있습니다.

int x = 5;
auto a = [=]() mutable { ++x; std::cout << x << '\n'; };
auto b = [&]()         { ++x; std::cout << x << '\n'; };

둘 다 수정할 수 있습니다 x. 차이점은 무엇입니까?


무슨 일이야

첫 번째는 자신의 사본 만 수정하고 x외부는 x변경하지 않습니다. 두 번째는 외부x 를 수정합니다 .

각각을 시도한 후 인쇄 문을 추가하십시오.

a();
std::cout << x << "----\n";
b();
std::cout << x << '\n';

다음과 같이 인쇄됩니다.

6
5
----
6
6

람다를 고려하는 것이 도움이 될 수 있습니다.

[...] 표현식은 간단한 함수 객체를 생성하는 간결한 방법을 제공합니다.

(표준의 [expr.prim.lambda] 참조)

그들은 가지고

[...] 공용 인라인 함수 호출 연산자 [...]

const멤버 함수 로 선언 되었지만

[...] 람다 식의 parameter-declaration-clause 가 뒤에 나오지 않는 경우에만mutable

당신은 마치

    int x = 5;
    auto a = [=]() mutable { ++x; std::cout << x << '\n'; };

==>

    int x = 5;

    class __lambda_a {
        int x;
    public:
        __lambda_a () : x($lookup-one-outer$::x) {}
        inline void operator() { ++x; std::cout << x << '\n'; }     
    } a;

    auto b = [&]()         { ++x; std::cout << x << '\n'; };

==>

    int x = 5;

    class __lambda_b {
        int &x;
    public:
        __lambda_b() : x($lookup-one-outer$::x) {}
        inline void operator() const { ++x; std::cout << x << '\n'; }         
        //                     ^^^^^
    } b;

Q : 하지만 const함수라면 왜 여전히 변경할 수 x있습니까?

A : 당신은 단지 외부를x 바꾸고 있습니다. 자신의 람다의는 x참조이며, 작업이 ++x수정하지 않습니다 참조 하지만, 대해 참조 값을 .

이것은 C ++에서 포인터 / 참조의 constness가 그것을 통해 보이는 pointee / referencee의 constness를 변경하지 않기 때문에 작동합니다.

참고 URL : https://stackoverflow.com/questions/16944894/c-lambdas-difference-between-mutable-and-capture-by-reference

반응형