나는 여전히 C++ 11의 이동 및 평가 절의 의미 개념을 배우고 있음을 이해해주십시오. 제 질문은 레거시 코드가 단순히 C++ 11 컴파일러와 STL을 사용하여 불필요한 복사본을 피하는 무료 점심을 먹을 수 있는지 여부입니다.C++ 11 rvalue and move : 레거시 코드가 복사본을 피할 수 있습니까?
다음은 매우 간단한 예입니다. 이 코드는 주어진 문자열에 대한 간단한 문자 빈도 테이블을 만듭니다. 예를 들어, "apple"은 {('a', 1), ('e', 1), ('l', 1), ('p', 2)}
을 반환해야합니다. 보시다시피, 저는 벡터를 값으로 사용하고 있습니다.
typedef std::tuple<char, int> Frequency;
typedef std::vector<Frequency> Frequencies;
Frequencies buildFrequenciesTable(std::string w) {
char table['z' - 'a' + 1] = { 0, };
std::for_each(w.cbegin(), w.cend(), [&table](char c) {
++table[::tolower(c) - 'a'];
});
Frequencies freqs;
for (size_t i = 0; i < 'z' - 'a' + 1; ++i) {
if (table[i] != 0)
freqs.push_back(tuple<char, int>((char) ('a' + i), table[i]));
}
return freqs; // Q1: Is vector get copied?
}
int main() {
using namespace std;
Frequencies f1 = buildFrequenciesTable("apple"); // Q2: Copy?
Frequencies f2 = buildFrequenciesTable("banana");
vector<Frequencies> fs = { f1, f2 }; // Q3: Copy?
}
이 값으로 벡터를 반환 할 때 C++ 03의 모든 사본 코드 (사용하는 복사 생성자와 대입 연산자)를 생성하는 것이 분명하다. C++ 11에서는 어떻습니까? std::vector
에는 이동 생성자가 있습니다. 이 코드가 unnessarry 복사본을 피할 수 있습니까? 또는 위의 코드에서 &&
또는 std::forward
을 사용해야합니까?
내부 STL 코드를 디버깅하려고 시도했지만 설득하기가 어려웠습니다.
참고 : 제 목표는 이러한 기능에서 불필요한 사본을 최소화하는 것입니다. 새로운/포인터/참조를 사용할 수 있지만 메모리 누수 문제를 해결해야합니다. 그래서 저는 가능한 한 많은 가치들을 사용하고 싶습니다.
고마워요! 따라서 Q1과 Q2의 경우에는 기본적으로 C++ 11의 r 값 참조 및 이동 의미에 따른 이점이 없습니다. 나는 정확하게 이해하고 있는가? – Nullptr
내 목표는 실제로 이러한 기능에서 불필요한 사본을 최소화하는 것입니다. 나는 새로운/포인터/참조를 사용할 수 있지만 이것은 미친 누출 문제가 필요할 것입니다. 그래서 저는 가능한 한 많은 가치들을 사용하고 싶습니다. – Nullptr
또 하나의 하위 질문 (어리석은 질문 일 수 있음) :이 코드를 더욱 최적화 할 수 있습니까? 예를 들어,'BuildFrequenciesTable'에'Frequencies &&'를 반환하거나'Frequencies && f1'을 선언 할 수 있습니다. 특히 위의'f1'과'f2'는 변경되지 않습니다. – Nullptr