2016-10-05 10 views
1

수명이 끝나기 전에 몇 개의 객체를 생성자로 전달하고 있습니다.const가 전달하는 것보다 이동이 더 비싼 이유는 ​​무엇입니까?

int main(){ 

    //I wanted to avoid short string optimization in this example. 
    const std::string a(25,"a"); 
    const std::string b(25,"b"); 
    const std::string c(25,"c"); 

    Foo f{a,b,c}; 
} 

Foo의 생성자에는 두 가지 옵션이 있습니다.

const& (호출 문자열의 복사 생성자) :

Foo(const std::string & a, 
    const std::string & b, 
    const std::string & c) 
:a(a) 
,b(b) 
,c(c) 
{} 

std::move (호출 문자열의 이동 생성자) :

+-------------+-----------------------+ 
| constructor | assembly instructions | 
+-------------+-----------------------+ 
| const&  |     192 | 
| move  |     264 | 
+-------------+-----------------------+ 
: gcc 7-01

Foo(std::string a, 
    std::string b, 
    std::string c) 
:a(std::move(a)) 
,b(std::move(b)) 
,c(std::move(c)) 
{} 

, 나는 다음과 같은 결과를 얻었다

이유는 0123입니다.지침이 부족합니까?
복사 생성자를 통해 새 문자열을 만드는 것보다 비용이 적게 듭니다.

변수를 생성자 인수로 전달하기위한 경험적 규칙은 무엇입니까
해당 인수의 수명이 끝나는 시점은 무엇입니까?

+2

'main'의'a, b, c'와 매개 변수에서'const'를 제거합니다; 함수 호출에서'move'를 사용하십시오. –

답변

5

이동 생성자를 호출하지 않습니다. 인수 문자열은 const입니다. 따라서 std::move을 사용하면 결과는 const std::string&&입니다. 그 이동 생성자를 호출하지 않습니다, 누구의 서명 걸릴 std::string&&.

+0

실수입니다. const *없이 * 호출했다. 가치로 전달하고 이동을 사용하면 같은 결과가됩니다. –

0

컴파일러는 생성자의 특별 버전을하지 않는 경우, main 여전히 서명 Foo(std::string a, std::string b, std::string c);

가 인라인, 또는 GCC가의 복제를하게하지 않는로 함수를 호출 전화를 주요 실제로 args를 다르게 전달하면 함수의 정의에있는 코드가 어떻게 호출되는지 변경할 수 없습니다.

생성자 정의가 별도의 파일에 있었고 main이 컴파일되는 동안 보이지 않았다고 가정하면 프로토 타입 만 표시됩니다. 이것은 -O1으로 컴파일하면 얻는 것과 비슷합니다.