티스토리 뷰

 이동 전용 객체들을 클로저 안으로 이동시키야 하는 경우를 알아보도록 하자. C++14 부터 새로운 갈무리 메커니즘을 도입하였다. 초기화 갈무리라는 것으로 다음과 같은 것을 할 수 있다.

class Widget {
public:
  ...
  bool isValidated() const;
  bool isProcessed() const;
  bool isArchived() const;
  
private:
  ...
};

auto pw = std::make_unique<Widget>();

...
auto func = [pw = std::move(pw)]
            { return pw->isValidated()
                     && pw->isArchived(); };

 마지막 줄에 캡쳐절이 초기화 갈무리라는 것이다. 재미있게도 좌변과 우변의 범위가 다른데, 좌변은 클로저의 범위이고 우변은 람다가 정의되는 지점의 범위와 같다. 아래와 같이 직접 초기화도 가능하다.

auto func = [pw = std::make_unique<Widget>()]
            { return pw->isValidated()
                     && pw->isArchived(); };

 문제는 C++11 에서 위와 같은 코드가 불가능하다는 것이다. 다음과 같이 작성할 수는 있다.

class IsValAndArch {
public:
  using DataType = std::unique_ptr<Widget>;
  
  explicit IsValAndArch(DataType&& ptr)
  : pw(std::move(ptr)) {}
  
  bool operator()() const
  { return pw->isValidated() && pw->isArchived();}
  
private:
  DataType pw;
};

auto func = IsValAndArch(std::make_unique<Widget>());

  위의 코드로 동작하게는 만들었지만 작성해야할 코드량이 너무 많다. 다행히도 C++11 에서 비슷한 동작을 지원하는 std::bind 함수가 있다.

std::vector<double> data;

// C++14
auto func = [data = std::move(data)]
            { ... };
            
// C++11
auto func =
  std::bind(
    [](const std::vector<double>& data)
    { ... },
    std::move(data)
  );

 std::bind 함수가 돌려주는 객체를 바인드 객체라고 부른다. 첫번째 인자는 호출 가능한 객체이고, 나머지는 그 객체에 전달할 값들을 나타낸다. 여기서 두번째 인자인 std::move(data) 가 전달하는 값이다. C++14 와의 차이점이라면 data 의 복사본을 사용한다는 것이다. 매개변수는 오른값이 전달되기는 했지만 람다 안에서 사용하는 data 는 복사본이기 때문이다. 위와 같은 이유로 상수성의 차이가 생기게 된다. 그 이유는 람다로부터 만들어진 클로저 클래스의 operator() 함수는 const 인데 반해 바인드로 이동 생성된 data 의 복사본은 const 가 아니기 때문이다. 그렇기 때문에 지금 보는 예제와 같이 const 에 대한 참조로 선언해야 한다. 만약 변이 가능한 람다를 사용하고 싶다면 mutable 로 선언하면 된다.

auto func =
  std::bind(
    [](std::vector<double>& data) mutable
    { ... },
    std::move(data)
  );

 

참고 서적

스콧 마이어스, Effective Modern C++
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함