나는 그것에 대해 걱정하지 않을 것입니다. 루프에서 수행하면 문자열은 항상 메모리를 미리 할당하여 재 할당을 최소화 operator+=
합니다.이 경우 에만 사용하십시오 . 수동으로하면 이런 식 이상이
a + " : " + c
그런 다음 컴파일러가 일부 반환 값 복사본을 제거 할 수 있더라도 임시 파일을 만듭니다. 연속적으로 호출 operator+
되면 참조 매개 변수가 명명 된 객체를 참조하는지 아니면 하위 operator+
호출 에서 반환 된 임시를 참조하는지 알지 못 하기 때문입니다 . 나는 먼저 프로파일 링하지 않기 전에 그것에 대해 걱정하지 않을 것입니다. 그러나 그것을 보여주는 예를 들어 봅시다. 바인딩을 명확하게하기 위해 먼저 괄호를 도입합니다. 명확성을 위해 사용되는 함수 선언 바로 뒤에 인수를 넣었습니다. 그 아래에서 결과 표현식이 무엇인지 보여줍니다.
((a + " : ") + c)
calls string operator+(string const&, char const*)(a, " : ")
=> (tmp1 + c)
이제 그 추가 tmp1
에서 표시된 인수를 사용하여 operator +에 대한 첫 번째 호출에서 반환 된 것입니다. 컴파일러가 정말 영리하고 반환 값 복사를 최적화한다고 가정합니다. 그래서 우리는 a
및 의 연결을 포함하는 하나의 새로운 문자열로 끝납니다 " : "
. 이제 이런 일이 발생합니다.
(tmp1 + c)
calls string operator+(string const&, string const&)(tmp1, c)
=> tmp2 == <end result>
다음과 비교하십시오.
std::string f = "hello";
(f + c)
calls string operator+(string const&, string const&)(f, c)
=> tmp1 == <end result>
임시 및 명명 된 문자열에 대해 동일한 기능을 사용하고 있습니다! 따라서 컴파일러 는 인수를 새 문자열에 복사하고 여기에 추가 한 다음 operator+
. 그것은 일시적인 기억을 가지고 그것에 추가 할 수 없습니다. 표현식이 클수록 더 많은 문자열을 복사해야합니다.
다음 Visual Studio 및 GCC는 실험적 추가 기능으로 c ++ 1x의 이동 의미 체계 ( 복사 의미 체계 보완 ) 및 rvalue 참조를 지원합니다. 이를 통해 매개 변수가 임시를 참조하는지 여부를 파악할 수 있습니다. 위의 모든 내용이 복사본없이 하나의 "파이프 라인 추가"로 끝나기 때문에 이러한 추가 작업은 놀랍도록 빠르게 이루어집니다.
병목 현상으로 판명되면 여전히 할 수 있습니다.
std::string(a).append(" : ").append(c) ...
append
호출에 인수를 추가 *this
하고 자신에 대한 참조를 반환합니다. 따라서 임시 복사가 수행되지 않습니다. 또는를 operator+=
사용할 수 있지만 우선 순위를 수정하려면보기 흉한 괄호가 필요합니다.