>

람다 함수를 사용할 때 (== 표기법으로) 변수를 복사하기로 결정했다고 가정 해 봅시다. 해당 변수를 다시 참조하지 않으면 컴파일러가 변수를 결과 함수 객체로 옮길 수 있습니까?

편집 : 예를 들어, 스레드 간 호출을 이동하는 스 니펫을 작성했습니다. 여기 샘플이 있습니다.

extern "C" __declspec(dllexport) void parser_file_updated(Parser* p, const char* filename, int offset, int added) {
     std::string file(filename);
     p->make_call([=]() {
         p->file_updated(std::move(file), offset, added);
     });
}

그러나 파일 변수는 람다 정의를 지나칠 필요가 없으며 실제로 람다는 한 번만 호출되므로 사본을 옮겼습니다.

  • 답변 # 1

    와이즈 비즈

    아니요. 컴파일러가 사본을 이동으로 대체 할 수있는 유일한 상황은 사본 제거를 수행 할 수있는 것과 동일한 상황입니다. 이러한 상황에는 값으로 로컬 오브젝트를 리턴하거나 임시로 오브젝트를 초기화하는 것이 포함됩니다. 이 경우 컴파일러는 소스와 대상을 동일한 객체로 만들어 복사본을 제거 할 수 있습니다. 컴파일러가 어떤 이유로 든 그렇게 할 수없는 경우 대상 객체에 적합한 생성자를 선택하기위한 과부하 해결과 관련하여 소스 객체를 rvalue로 고려해야합니다. 그러나 귀하의 경우 파일은 L 값이며 위의 경우 중 어느 것도 적용되지 않습니다. 명시적인 이동을 사용해야합니다.

    불행히도 C ++ 11에는 "이동 캡처"에 대한 구문이 없습니다. IMHO, 부끄러운 일입니다. 그러나 std :: bind는 이것을 지원합니다. std :: bind를 다음과 같은 람다 식과 결합 할 수 있어야합니다.

    If you never reference that variable again, is the compiler allowed to move it into the resultant function object?

    문자열이 함수 객체로 이동되도록

    이 함수를 한 번만 호출하고 문자열을 함수 객체 밖으로 다시 이동 시키려면, 상수가 아닌 참조를 사용할 수 있습니다 :

    void foo(char const* p) {
       string s = p;
       auto fun = bind([](string const& s){
          ...
       },move(s));
       fun();
    }
    
    

    여기에서 bind를 사용하지 않고 lambda 객체의 생성자가 s 복사본을 만들도록하려면 함수 객체에서 문자열을 이동하려면 가변 키워드가 필요합니다.

    void foo(char const* p) {
       string s = p;
       auto fun = bind([](string & s) {
          some_other_func(move(s));
       },move(s));
       fun();
    }
    
    

    그렇지 않으면 클로저 타입의 operator () 함수가 const-qualified되어 void foo(char const* p) { string s = p; auto fun = [=]() mutable { // ^^^^^^^ some_other_func(move(s)); }; fun(); } 가됩니다.  const 한정 문자열.

    C ++ 14에서는 람다 캡처 절이 좀 더 유연 해졌습니다. 이제 쓸 수 있습니다

    s
    
    

    여기서 # 1은 문자열 값을 람다 객체로 이동하고 # 2는 문자열 값을 밖으로 이동시킵니다 ( void foo(char const* p) { string s = p; auto fun = [s=move(s)]() mutable { // #1 some_other_func(move(s)); // #2 }; fun(); } 방법에 따라 다름)  정확하게 선언됩니다).

    some_other_func

  • 이전 c# - 잠금 사용시기에 대한 지침
  • 다음 python : Pandas 데이터 프레임을 사용할 때 존재하지 않는 경우 어떻게 열을 추가합니까?