C++/Effective Modern C++32 객체를 클로저 안으로 이동하려면 초기화 갈무리를 사용하라 C++11에서는 이동 전용 객체들(std::unique_ptr, std::future 등)을 클로저 안으로 들여올 수가 없다. 또한 복사는 비싸고 이동은 저렴한 객체를 클로저 안으로 들여온다면 복사보다는 이동이 적용되는 것이 바람직한데 역시 불가능하다. C++14에서는 객체를 클로저 안으로 이동하는 수단을 직접 제공한다. 이동 갈무리를 위해 새로운 갈무리 메커니즘을 도입했는데 그것을 초기화 갈무리 라고 한다. 초기화 갈무리는 람다로부터 생성되는 클로저 클래스에 속한 자료 멤버의 이름과 그 자료 멤버를 초기화하는 표현식을 지정할 수 있다. 다음은 초기화 갈무리의 한 예이다. class Widget{ public: ... bool isValidated() const; bool isProcessed() con.. 2020. 8. 6. 람다표현식에서 기본 갈무리 모드는 피하자 C++11의 기본 갈무리 모드는 두가지로 하나는 참조에 의한 갈무리 모드, 또 하나는 값에 의한 갈무리 모드이다. 기본 참조에 의한 갈무리 모드는 참조 대상을 잃을 위험이 있으며, 값에 의한 갈무리 모드 또한 참조가 대상을 잃는 문제를 갖고있으며, 자기 완결적이지 않은 경우가 있다. 참조 갈무리를 사용하는 클로저는 지역 변수 또는 람다가 정의된 범위에서 볼 수 있는 매개변수에 대한 참조를 가지게 된다. 람다에 의해 생성된 클로저의 수명이 그 지역변수나 매개변수의 수명보다 오래 지속되면, 클로저 안의 참조는 대상을 잃는다. 예를들어 int 하나를 받아 그 값이 필터를 만족하는지 뜻하는 bool 하나를 돌려주는 필터링 함수들을 담는 컨테이너가 있다고 하자 using FilterContainer = std::.. 2020. 8. 3. 완벽전달이 실패하는 경우들 2 중복적재된 함수 이름과 템플릿 이름 1편에서의 함수 f와 마찬가지로 fwd를 거쳐 인수를 전달하려는 대상 함수의 행동 방식을 커스텀 하기위해 f가 하나의 함수를 받아서 그 함수를 호출한다고 하자. 그함수가 int를 받고 int를 돌려준다고 하자 void f(int (*pf)(int));// pf는 processing function void f(int pf(int));// 더 간단한 비 포인터 구문 여기에 중복 적재된 processVal 함수가 있다고 하자 int processVal(int value); int processVal(int value, int priority); f(processVal);// 가능하다 f는 함수 포인터를 기대하지만 processVal은 함수 포인터가 아니다. 함수또한 아니다.. 2020. 7. 30. 완벽 전달이 실패하는 경우들 1 우선 완벽 전달에 대해 알아보도록 하자 전달(forwarding)이란 말 그대로 한 함수가 자신의 인수들을 다른 함수에 넘겨주는(전달하는) 것을 뜻한다. 이때 목표는 전달받는 함수가 애초에 전달하는 함수가 받았던 것과 동일한 객체들을 받게 하는 것이다. 하지만 값 전달 방식의 매개변수로는 불가능하다. 매개변수는 원래 호출자가 넘겨준 인수의 복사본이기 때문이다. 그래서 범용적인 전달을 위해 참조 매개변수들을 사용해야 한다. 완벽 전달은 단순히 객체들을 전달하는 것 뿐만 아니라 그 객체의 특징과 형식(왼값/오른값 여부, const/volatile 여부)도 전달하는 것을 말한다. f라는 함수에 인수를 전달하는 함수를 만들어 보자. 전달 함수는 임의의 형식과 개수의 인수들을 받는 템플릿 이어야 하기 때문에 가변.. 2020. 7. 29. C++11에서 이동 의미론이 항상 도움이 될까 결론부터 말하자면 아니다. 아마도 C++ 에서 가장 주된 기능은 이동 의미론일 것이다. 이로 인해 컴파일러는 비싼 복사 연산을 비교적 저렴한 이동 연산으로 대체할 수 있을 뿐 아니라 적절한 조건이 만족되면 반드시 대체해야 한다. 하지만 이동의미론을 지원하지 않는 형식들이 많고, 사용자 정의 형식들은 C++11에 완전히 맞게 수정되지 않았다면 컴파일러가 이동을 지원해도 응용 프로그램의 성능이 저절로 높아지지는 않는다. 이동을 명시적으로 지원하더라도 성능상의 이득이 크지 않을 수 있다. 컨테이너의 내용을 저렴하게 이동하는 방법이 없을 수도 있고, 컨테이너가 제공하는 저렴한 이동연산이 요구하는 까다로운 조건을 컨테이너 요소들이 만족하지 못하는 경우도 있을 수 있다. 그 예로 std::array가 있다. std.. 2020. 7. 28. 참조축약을 숙지하라 template void func(T&& param); Widget widgetFactory();// 오른값을 돌려주는 함수 Widget w;// 변수 (왼값) func(w);// func를 왼값 호출, T는 Widget&로 연역 func(widgetFactory());// func를 오른값 호출, T는 Widget으로 연역 두 func 모두 Widget이 전달되지만 Widget이 왼값인지 오른값인지에 따라 템플릿 매개변수 T에 대해 연역되는 형식이 다르다. 보편참조가 오른값/왼값 중 어느 값 참조가 될 것인지 결정한다. 그리고 이 메커니즘은 std::forward의 기본이 된다. 우선 C++에서 참조에 대한 참조는 위법이다. 하지만 보편 참조를 받는 함수 템플릿에 왼값을 넘겨주는 것은 컴파일이 된다. .. 2020. 7. 27. 이전 1 2 3 4 ··· 6 다음