-
항목26. 보편 참조에 대한 중복적재를 피하라Effective Modern C++ 2022. 9. 6. 20:16
std::multiset<std::string> names; void logAndAdd(const std::string& name){ ... names.emplace(name); // 전역 자료구조에 추가한다. }이때 오른값이나 문자열 리터럴을 매개변수로 넘겨주면 비효율적인 작동을 한다.
오른값은 이동을 할 수 있지만 복사를 수행하고, 문자열 리터럴은 std::multiset에 직접 생성할 수 있지만 임시 객체 생성과 복사를 수행한다. 이런 낭비를 줄이기위해 보편 참조를 사용해보자
template<typename T> void logAndAdd(T&& name){ ... names.emplace(std::forward<T>(name)); } std::string petName("Darla"); logAndAdd(petName); // 복사 logAndAdd(std::string("Persephone")); // 이동 logAndAdd("Patty Dog"); // multiset 안에 직접 생성보편 참조에 대한 중복적재를 하면 컴파일러는 정확히 일치하지 않는 이상 대부분 보편 참조에 해당하는 함수&생성자를 수행한다. 예를 들어 int 형 중복적재에 short형을 넣어 (short에서 int로의) 승격을 통해 int 형 중복적재 함수를 호출하고 싶어도 보편 참조 함수가 호출된다. 다음 같은 경우도 그렇다.
class Person{ public: template<typename T> explicit Person(T&& n) // 완벽 전달 생성자 : name (std::forward<T>(n)){} // Person(const Person& rhs); // 복사 생성자 컴파일러에 의해 자동 작성됨 // Person(Person&& rhs); // 이동 생성자 컴파일러에 의해 자동 작성됨 } Person p("Nancy"); auto cloneOfP(p); // 완벽 전달 생성자 호출, 컴파일 실패 const Person cp("Gaues"); auto cloneOfP(cp) // 복사 생성자를 호출'Effective Modern C++' 카테고리의 다른 글
항목28. 참조 축약을 숙지하라 (0) 2022.09.07 항목27. 보편 참조에 대한 중복적재 대신 사용할 수 있는 기법들을 알아 두라 (0) 2022.09.06 항목25. 오른값 참조에는 std::move를, 보편 참조에는 std::forward를 사용하라 (0) 2022.08.27 항목24. 보편 참조와 오른값 참조를 구별하라 (0) 2022.08.27 항목23. std::move와 std::forward를 숙지하라 (0) 2022.08.20