2017-10-27 6 views
1

나는 std::bindstd::movestd::unique_ptr에두고 있습니다. 결과 함수 객체는 불변 인 것으로 보이므로 함수를 호출 할 때 이동을 수행하는 것은 불가능합니다.std :: bind의 가변 버전이 있습니까?

이것이 람다가 기본적으로 변경 불가능한 이유와 동일한 이유 때문이라고 생각됩니다. 호출 할 때마다 동일한 작업을해야합니다. 그러나 그들이 변경 가능해야하는 경우가 있으므로, 우리는 mutable 키워드를 가지고 있습니다.

void foo(std::unique_ptr<int>&& ptr) 
{ 
    cout << *ptr << endl; 
} 

int main() 
{ 
    std::unique_ptr<int> ptr = std::make_unique<int>(123); 
    std::bind(foo, std::move(ptr))();    // Doesn't compile 
    [&ptr]() { foo(std::move(ptr)); }();   // Equivalent, doesn't compile 
    [&ptr]() mutable { foo(std::move(ptr)); }(); // Compiles 
    return 0; 
} 

Instad는 bind를 사용하는 나는 변경 가능한 람다의 함수 호출을 래핑 할 수있다. 그러나 나에게 최소한 개인적으로 bind은이 경우 훨씬 더 깔끔하고 단순 해 보인다.

변경 가능한 람다를 두 번 호출하면 정의되지 않은 동작이 발생할 수 있다는 것을 이해합니다. 이미 이동 된 포인터에서 다시 이동하기 때문입니다. 하지만 제 경우에는 펑터가 한 번만 호출된다는 것을 알고 있습니다.

이렇게하려면 std::bind을 사용할 수있는 방법이 있습니까? 종류가 bind_mutable입니까? 그렇지 않다면 어떻게 직접 작성해야합니까?

+2

귀하의 주장이 잘못되었습니다. 둘 다 람다 작품 : [Demo] (http://coliru.stacked-crooked.com/a/b21ee8e7d660955b). bind에 필요한 것은'rvalue_refence_wrapper'입니다. [is-there-a-reference-wraval-for-rvalue-references] (https://stackoverflow.com/questions/5126219/is-there-a-reference-wrapper-for-rvalue-references)를 참조하십시오. – Jarod42

+0

[tag : C++ 11]에 실제로 갇혀 있습니까? 아니면 컴파일러에 [tag : C++ 14] 기능이 있습니까? 여기에서'bind '에 대한 필요성은 기본적으로 [tag : C++ 14]에서 사라 졌기 때문에. – Yakk

답변

2

그러나 적어도 나에게 개인적으로 바인딩하는 것은이 경우 훨씬 더 깔끔하고 단순 해 보입니다.

C++에서 std::bind을 사용하지 마십시오. 대신 람다를 사용하십시오. std::bind에는 몇 가지 문제가 있습니다. excellently explained in this talk by Stephan T. Lavavej “functional: What's New, And Proper Usage".

screenshot from talk

그것은이 경우 간단하고 깨끗한 보일 수 있습니다, 그러나하지 않는 것이 좋습니다.

쓰기 ...

[&ptr]{ foo(std::move(ptr)); }(); 

는 ...이 문제를 해결하는 올바른 방법입니다.

+1

'[& ptr]() {foo (std :: move (ptr)); }();'충분하다. – Jarod42

+0

'& ptr' 구문의 단점은 람다가 현재 스택 컨텍스트 밖으로 복사/이동 될 수 없다는 것입니다. C++ 14가 이것을 해결합니다. – Yakk