C ++ 자동 및 자동


88

지역 변수를 만들 때 (const) auto&또는 사용하는 것이 맞 auto습니까?

예 :

SomeClass object;
const auto result = object.SomeMethod();

또는 const auto& result = object.SomeMethod();

SomeMethod ()는 원시 값이 아닌 값을 반환합니다. 다른 사용자 정의 유형일 수도 있습니다. 내 이해는 const auto& resultSomeMethod ()에 의해 반환 된 결과가 반환 된 형식에 대한 복사 생성자를 호출하기 때문에 정확합니다. 내가 틀렸다면 나를 고쳐주세요.

원시 유형은 어떻습니까? 나는 const auto sum = 1 + 2;옳다고 생각한다 .

범위 기반 for 루프에도 적용됩니까?

for(const auto& object : objects)

1
이 글을 읽어 보시기를 강력히 추천합니다 : safaribooksonline.com/library/view/effective-modern-c/… 처음 두 장은 무료이며 템플릿 유형 추론을 설명합니다. 기본적으로 auto작동 하는 방식입니다 (특이한 initializer_lists의 경우 제외). 템플릿 컨텍스트에서 추론되지 않음), autodeduction 을 입력합니다.
vsoftco 2015

답변:


102

auto그리고 auto &&대부분의 경우를 포함합니다 :

  • auto로컬 사본이 필요할 때 사용하십시오 . 이것은 참조를 생성하지 않습니다. 복사 (또는 이동) 생성자가 있어야하지만 복사 제거 최적화 로 인해 호출되지 않을 수 있습니다 .

  • auto &&객체가 로컬인지 아닌지 상관하지 않을 때 사용 합니다. 기술적으로 이것은 항상 참조를 생성하지만 이니셜 라이저가 일시적인 경우 (예 : 함수가 값으로 반환 됨) 기본적으로 로컬 객체처럼 동작합니다.

    또한 auto &&개체가 수정 가능하다는 보장도 없습니다. const객체 또는 참조가 주어지면 const. 그러나 특정 컨텍스트를 고려할 때 수정 가능성이 종종 가정됩니다.

auto &그리고 auto const &좀 더 구체적인 :

  • auto &변수를 다른 것과 공유하고 있음을 보장합니다. 항상 참조이며 일시적인 것이 아닙니다.

  • auto const &과 유사 auto &&하지만 읽기 전용 액세스를 제공합니다.

원시 / 비 원시 유형은 어떻습니까?

다른 점이 없다.

범위 기반 for 루프에도 적용됩니까?

예. 위의 원칙을 적용하여

  • auto &&루프 내에서 시퀀스 값을 수정하고 버리는 기능에 사용 합니다. (즉, 컨테이너가과 같은 읽기 전용보기를 제공하지 않는 한, std::initializer_list이 경우 사실상 auto const &.)
  • auto &의미있는 방식으로 시퀀스 값을 수정하는 데 사용 합니다.
  • auto const &읽기 전용 액세스에 사용 합니다.
  • auto(수정 가능한) 사본 작업에 사용 합니다.

당신은 또한 auto const참조없이 언급합니다. 이것은 작동하지만 이미 소유하고있는 항목에 대한 읽기 전용 액세스의 이점이 거의 없기 때문에 일반적으로 사용되지 않습니다.


셔터는 자동 및 트랙 const와 말한다
제시 페퍼

1
@JessePepper 네. (하지만 권위에 호소하는 것은 약간 이상합니다.) 이것의 특정 부분을 언급하고 있습니까?
Potatoswatter

본질적 auto&으로 좋은 선택 인 것 같습니다. 그러나 const auto&아직 존재하지 않는 constness를 추가하고 싶을 때 사용 합니다. auto&&Sutter가 생각하는 것보다 더 자주 발생한다고 생각합니다. 예를 들어, 반환 값을 저장 한 auto&&다음 std :: cout과 같은 두 가지로 "전달"하여 디버깅 값을 확인하고 다른 함수에 전달할 수도 있습니다. 나는 auto &&를 더 자주 사용했지만 예상치 못한 일을 할 때 한두 번 물렸다. 무엇이 잘못되었는지 더 많이 알아 차렸으면 좋겠습니다!
Jesse Pepper

@JessePepper 예, auto&&누락 된 언어 기능과 관련이 있으며, 모든 문을 더 작은 문으로 나눌 수 있어야 합니다. 빠진 부분은 수명 연장입니다.이 문제를 해결하기 위해 많은 노력을 기울 였지만 아무도 눈치 채지 못했습니다.
punditry

자동 const : auto const x = fn (); 함수가 참조를 반환하지 않는다는 것을 알고 있고 객체 x가 변경되지 않기를 원하면 버그를 방지하거나 범위에서 사용되는 것을 문서화합니다. 같은 방식으로 일반적으로 작성하지 않습니다. const int & x = 1; 그러나 auto const &는 이런 식으로 선언 된 참조에 대한 수명 확장 규칙으로 인해 동등한 결과를 제공합니다.
Spacen Jasset

47

예, 그것은 사용하여 정확 auto하고 auto&지역 변수. 함수의 반환 유형을 가져올 때를 사용하는 것도 정확합니다 auto&. 이는 범위 기반 for 루프에도 적용됩니다.

사용 auto에 대한 일반적인 규칙 은 다음과 같습니다.

  • auto x사본으로 작업 할시기를 선택하십시오 .
  • 고르다 auto &x원본 항목으로 작업 할시기를 하고 수정할 수 있습니다.
  • 선택 auto const &x당신이 원래 항목을 작업 할하고이를 수정하지 않습니다 때.

여기 에서 자동 지정자에 대해 자세히 읽을 수 있습니다 .


9

auto템플릿과 같은 형태 추론의 동일한 메커니즘, 내가 그 추론하는 중괄호 초기화하기 목록의 존재의 알고있는 유일한 예외 사용 auto등을 std::initializer_list하지만, 템플릿 맥락에서 비 추론.

auto x = expression;

먼저 오른쪽 표현식의 유형에서 모든 참조 및 cv 한정자를 제거한 다음 유형을 일치시키는 방식으로 작동합니다. 예를 들어, 당신이있는 경우 const int& f(){...}다음 auto x = f();추론 x으로 int하고, 하지 const int& .

다른 형태는

auto& x = expression

제거하지 않고 , 위의 예를 사용하여, 따라서, CV-한정자 auto& x = f()추론을 x같이 const int&. 다른 조합은 cv 한정자를 추가합니다.

유형이 항상 cv-ref 한정자로 추론되도록 decltype(auto)하려면 decltype유형 추론 규칙 을 사용하는 C ++ 14에서 악명 높은 것을 사용하십시오 .

따라서 간단히 말해서 사본을 원하면을 사용 auto하고 참조를 원하면 auto&. const추가적인 const-ness 를 원할 때마다 사용하십시오 .


편집 추가 사용 사례가 있습니다.

auto&& x = expression;

템플릿 코드에서 참조를 전달하는 경우와 동일한 참조 축소 규칙을 사용합니다. 경우 expression좌변은 다음 x의 CV-한정자와 좌변 기준이다 expression. 경우 expression를 rvalue이며, 다음 x를 rvalue 참조입니다.


@Potatoswatter 감사합니다. 나는 실제로 rvalues. 간단한 테스트 방법이 있습니까? 그리고 cv-qualified rvalue를 어떻게 가질 수 있습니까? 함수 반환에서 cv는 폐기됩니다.
vsoftco 2015

아니요, 함수 반환시 폐기되지 않습니다. 모든 스칼라 유형 (C ++ 14 [및 기타 에디션] §5 / 6)의 prvalue에 대해 폐기됩니다. 함수 호출 또는 캐스트 표기법을 사용하여 얻을 수 있습니다. Cv로 한정된 xvalue auto && x = std::move< const int >( 5 );는 다른 것과 동일하게 작동합니다 int const && x. 거의 사용되지는 않지만을 선언 합니다.
Potatoswatter

@ Potatoswatter 감사합니다, 당신이 맞습니다, 내 실수. 나는 먼저 POD로 테스트했는데,이 경우 cv가 폐기되고 이것이 일반적인 경우라고 생각했습니다. 물론 일반적으로 cv를 보존하기를 원할 수 있으므로 버려서는 안됩니다 (예 : rvalue 반환시 ​​상수가 아닌 멤버 함수를 호출 할 수 없음).
vsoftco 2015

스칼라 유형의 경우 삭제됩니다. POD는 수업 일 수 있습니다. 어쨌든, 그것은 표현 모델과 객체 모델의 교차점의 끔찍한 구석입니다.
Potatoswatter 2015

2

지역 변수를 만들 때 (const) auto & 또는 auto를 사용하는 것이 맞습니까?

예. auto는 컴파일러에서 파생 된 유형에 지나지 않으므로 일반적으로 참조를 사용하는 경우 참조를 사용하고 일반적으로 로컬 복사본을 사용하는 경우 로컬 (자동) 복사본을 사용합니다. 참조 사용 여부는 유형 추론과 무관합니다.

SomeMethod ()는 원시 값이 아닌 값을 반환합니다. 다른 사용자 정의 유형일 수도 있습니다. 내 이해는 SomeMethod ()에 의해 반환 된 결과가 반환 된 형식에 대한 복사 생성자를 호출하기 때문에 const auto & 결과가 정확하다는 것입니다. 내가 틀렸다면 나를 바로 잡으십시오.

적법한? 예, const. 모범 사례? 아마 아닐 것입니다. 적어도 C ++ 11에서는 그렇지 않습니다. 특히 SomeMethod ()에서 반환 된 값이 이미 임시 인 경우에는 그렇지 않습니다. C ++ 11 이동 의미론, 복사 제거 및 반환 값 최적화에 대해 배우고 싶을 것입니다 : https://juanchopanzacpp.wordpress.com/2014/05/11/want-speed-dont-always-pass-by- 값/

http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=199

https://isocpp.org/wiki/faq/ctors#return-by-value-optimization

원시 유형은 어떻습니까? 나는 const auto sum = 1 + 2라고 가정합니다. 맞다.

네, 괜찮습니다.

범위 기반 for 루프에도 적용됩니까?

for (const auto & object : 객체)

네, 이것도 괜찮습니다. 저는 항상 직장에서 이런 종류의 코드를 작성합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.