2016-07-27 7 views
1

하자 우리가 반환하는 함수가 있다고 가정 std::string 같은 복잡한 객체 :const auto & 함수 결과 저장 용으로 가치가 있습니까?

std::string find_path(const std::string& filename); 

const auto&에서 해당 메소드를 호출 한 결과를 저장하는 가치인가?

void do_sth() { 
    //... 
    const auto& path = find_path(filename); 
    //... 
} 

이런 종류의 접근 방식은 객체의 복사/이동을 방지합니다. 그래서 좋다. 그러나 반면에 auto은 할당의 왼쪽을 통합하기 위해 도입되었습니다. CppCon2014의 프레젠테이션에서 Herb Sutter는 C++ 왼쪽에서 오른쪽으로 모던 한 스타일 https://www.youtube.com/watch?v=xnqTKD8uD64 (39 : 00-45 : 00)에 대해 언급합니다.

const 레퍼런스에서 std::string을 저장하는 C++ 98에서는 괜찮 았습니다. C++ 11에서는 어떻게됩니까?

업데이트 (2016년 7월 27일 2:10 GMT + 0) :

죄송합니다, 내 질문은 정확하지 않았다. 나는 코딩 스타일을 의미했습니다. const &을 추가하거나 auto 만 남겨두고 컴파일러에서 원하는대로 수행하도록하는 것이 더 좋습니다.

업데이트 된 예 :

unsigned int getTimout() { /* ... */ } 

int getDepth() { /* ... */ } 

std::string find_path(const std::string& filename, 
         unsigned int timeout, 
         int depth) { /* ... */ } 

void open(const std::string& path) { /* ... */ } 

두 가지 접근 방법 :

void do_sth() { 
    //... 
    auto timeout = getTimeout(); 
    auto depth = getDepth(); 
    const auto& path = find_path(filename, timeout, depth); 
    open(path) 
    //... 
} 

void do_sth() { 
    //... 
    auto timeout = getTimeout(); 
    auto depth = getDepth(); 
    auto path = find_path(filename, timeout, depth); 
    open(path); 
    //... 
} 

대 질문 :해야 우리

  • const auto&을 사용하여 복잡한 반환 객체와
  • 을 사용하여 Herb가 자신의 프레젠테이션 (위 링크)에서 언급 한 왼쪽에서 오른쪽의 현대 C++ 스타일을 유지하는 모든 것에 대해 사용하십시오.
+1

임시로 참조로 반환하지 마십시오 (함수 반환 값 가져 오기). –

+2

NVRO에 대한 정보가 필요합니다. http://stackoverflow.com/questions/6233879/move-or-named-return-value-optimization-nrvo –

+4

@ DieterLücking "C++은 의도적으로 임시 개체를 스택을 사용하면 임시의 수명이 참조 자체의 수명보다 길어집니다. " https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-most-important-const/ –

답변

2

const 레퍼런스에서 std :: string을 저장하는 것은 괜찮았다. C++ 11에서는 어떻게됩니까?

C++ 11에서는 임시 문자열 개체에 대한 const 참조를 바인딩하는 것이 좋습니다. 이전과 동일한 동작을 유지합니다.

문자열을 이동하는 것이 복사하는 것보다 훨씬 저렴하기 때문에 C++ 11에서는 임시 참조로부터의 복사 초기화의 이론적 인 비용 (const 참조 사용의 이점을 피할 수 있음)이 크게 줄어 들었습니다.

복사 초기화의 실제 비용은 컴파일러 최적화에 따라 변경되지 않았기 때문에 복사/이동이 취소 될 수 있으므로 비용은 들지 않습니다. 그러나 가능한지 여부는 find_path의 구현 방법에 따라 다릅니다.


당신이 절대적으로 반환 된 문자열을 이동/복사를 피하려고하고, 복사 생략을지지 않습니다 다음 함수 외부의 객체를 생성해야하며, 참조로 함수에 전달합니다.반환 값에 대한 참조를 바인딩하는 것만으로는 충분하지 않습니다.

반환 된 문자열을 복사/이동하는 것을 피하고 사본 추출을 가정 할 수 있으면 일반 객체를 사용하는 것이 const 참조와 똑같습니다.