C++/Effective Modern C++32 보편참조에 대한 중복적재 대신 사용할 수 있는 기법들을 알아두라 2 보편참조를 받는 템플릿을 제한한다. std::enable_if는 컴파일러가 특정 템플릿을 존재하지 않는 것처럼 할 수 있다. 그런 템플릿을 비활성화된 템플릿이라고 한다. 기본적으로 모든 템플릿은 활성화 상태이지만 std::enable_if를 사용하는 경우, 특정 조건이 만족될 때에만 활성화된다. 일단 기존의 예제에 std::enable_if만 추가해보자 class Person{ public: template explicit Person(T&& n); ... }; // std::enable_if와 그 작동원리인 SFINAE는 나중에 따로 정리 여기서 우리가 지정하려고 하는 조건은 T가 Person이 아니라는 것이다. 이것을 판별할 유용한 형식특질로 두 형식이 같은지를 판별하는 std::is_same이 있다.. 2020. 7. 23. 보편참조에 대한 중복적재 대신 사용할수 있는 기법들 1 1. 중복적재를 포기한다 중복 적재 버전에 각자 다른 이름을 붙여 보편 참조에 대한 단점을 피할 수 있다. 하지만 생성자의 이름은 언어에 의해 고정되기 때문에 중복적재가 필요할 수 있다. 2. const T& 매개변수를 사용한다. 보편 참조 매개변수 대신 const에 대한 왼값 참조 매개변수를 사용한다. 이런 설계는 원하는 만큼 효율적이지 않다. 3. 값 전달 방식의 매개변수를 사용한다 참조 전달 매개변수 대신 값 전달 매개변수를 사용한다. 복사될 것이 확실한 객체는 값으로 전달하는 것을 고려하는 것이 좋다. 앞에 설명했던 예제의 Person을 사용해 결과를 보도록 하자 class Person { public: explicit Person(std::string n)// T&& 생성자를 대체한다 : nam.. 2020. 7. 22. 보편 참조에 대한 중복적재를 피하라 // 사람 이름 하나를 매개변수로 받고, 현재 날짜와 시간을 기록하여 전역 자료구조에 추가하는 예제 std::multiset names;// 전역 자료구조 void logAndAdd(const std::string& name) { auto now = std::chrono::system_clock::now();// 현재 시간을 얻고 log(now, "logAndAdd");// 로그에 기록 names.emplace(name);// 이름을 전역 자료구조에 추가 } std::string petName("Darla"); logAndAdd(petName);// 왼값 std::string을 넘겨줌 logAndAdd(std::string("Persephone"));// 오른값 std::string을 넘겨줌 logAnd.. 2020. 7. 21. std::move, std::forward std::move와 std::forward는 캐스팅을 수행하는 함수(함수 템플릿)이다. std::move는 주어진 인수를 무조건 오른 값으로 캐스팅하고, std::forward는 특정 조건이 만족될 때에만 캐스팅을 수행한다. std::move를 구현해보자 template// C++11 버전 typename remove_reference::type&& move(T&& param) { using ReturnType = typename remove_reference::type&&; return static_cast(param); } template// C++14 버전, remove_reference_t와 decltype 사용 decltype(auto) move(T&& param) { using ReturnTy.. 2020. 7. 17. Pimpl 관용구를 사용할 때에는 특수 멤버 함수들을 구현 파일에서 정리하라 Pimpl 관용구는 클래스의 자료 멤버들을 구현 클래스 또는 구조체를 가리키는 포인터로 대체하고, 일차 클래스에 쓰이는 자료 멤버들을 그 구현 클래스로 옮기고, 포인터를 통해 그 자료 멤버들에 간접적으로 접근하는 방법이다. 일반적으로 헤더의 의존도를 떨어뜨리고, 컴파일 시간을 단축해 준다. 기존 C++98에서의 구현 방법 예시이다. // "widget.h" class Widget { public: Widget(); ... private: std::string name; std::vector data;// 헤더 내에 #include , #include 필요 Gadget g1, g2, g3; }; // Pimpl 관용구 적용 class Widget { public: Widget(); ~Widget();// .. 2020. 7. 16. new 보다 std::make_shared와 make_unique를 선호하라 std::make_shared는 C++11의 일부지만 std::make_unique는 C++14에 와서 표준 라이브러리에 포함되었다. 하지만 간단하게 구현할 수 있다. template// C++11 용으로 구현한 make_unique std::unique_ptr make_unique(Ts&&... params) { return std::unique_ptr(new T(std::forward(params)...)); } new 보다 make 함수를 선호해야하는 첫번째 이유로는 코드의 중복을 없애는데 있다. auto upw1(std::make_unique());// make 함수를 사용 std::unique_ptr upw2(new Widget);// 사용하지 않음 되풀이되는 Widget의 중복을 없앨 수 있다.. 2020. 7. 15. 이전 1 2 3 4 5 6 다음