루프에서 새로운 C ++ 11 ‘자동’기능을 사용해야합니까? 사용할 때의 장단점은 무엇입니까

auto특히 for 루프에서 키워드 를 사용할 때의 장단점은 무엇입니까 ?

for(std::vector<T>::iterator it = x.begin(); it != x.end(); it++ )
{
   it->something();
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); it++ )
{
   it->second->something();
}

for(auto it = x.begin(); it != x.end(); it++ )
{
   it->??
}

당신이지도 또는 당신이 모르는 것 벡터에 대한 반복자를 가지고 있는지 모르는 경우처럼 보인다 사용 여부를 first하거나 second또는 개체의 바로 직접 액세스 속성, 아니?

키워드 사용 여부에 대한 C # 토론을 생각 나게합니다 var. 내가 지금 얻는 인상은 C ++ 세계에서 사람들이 C # 세계 auto보다 싸울 필요없이 키워드 를 채택 할 준비가되어 있다는 것 var입니다. 저에게 제 첫 번째 본능은 변수의 유형을 알고 싶어서 어떤 연산을 수행 할 수 있는지 알 수 있다는 것입니다.



답변

메타 프로그래밍 및 기타 사항으로 인해 유형이 C # 유형보다 훨씬 복잡하고 복잡해질 수 있으므로 C ++의 동기는 더 극단적입니다. auto명시 적 유형보다 쓰기 및 읽기 속도가 빠르고 유연하고 유지 관리가 가능합니다. 내 말은, 타이핑을 시작하고 싶니?

boost::multi_map<NodeType, indexed_by<ordered_unique<identity<NodeType>>, hashed_non_unique<identity<NodeType>, custom_hasher>>::iterator_type<0> it

그것은 완전한 유형조차 아닙니다. 몇 가지 템플릿 인수를 놓쳤습니다.


답변

귀하의 예에서 :

for(auto it = x.begin(); it != x.end(); i++)
{
  it->??
}

x보이는 선언이 있어야합니다 . 따라서 유형 it이 분명해야합니다. 유형이 x명확하지 않으면 메서드가 너무 길거나 클래스가 너무 큽니다.


답변

이의 제기 ! 로드 된 질문입니다.

세 번째 코드가 왜 포함되어 있는지 설명 할 수 있습니까 ???하지만 첫 번째와 두 번째 코드는 그렇지 않습니다. 공정성을 위해 코드 다음과 같이 읽어야합니다.

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->???
}

for(std::map<T>::iterator it = x.begin(); it != x.end(); i++)
{
   it->second->???
}

그곳에. 를 사용하지 않아도 동일한 문제가 발생합니다 auto.

그리고 모든 경우에 대한 답은 동일합니다 : 상황이 중요 합니다. 독립적으로 코드 조각에 대해 의미있게 이야기 할 수는 없습니다. 템플릿을 사용하지 않고 구체적인 유형을 사용하더라도 코드 독자는 해당 유형의 선언에 대해 알아야하기 때문에 문제를 다른 곳으로 이동했을 것입니다.

사용하는 경우 auto이러한 상황에서이 코드를 렌더링 당신은 당신의 코드 디자인 뭔가 잘못이 있다는 경고 표시로이 문제를 처리해야 읽을. 물론, 비트 연산이나 레거시 API를 처리 할 때와 같이 하위 수준의 세부 정보가 중요한 경우에는 명시 적 형식이 가독성에 도움이 될 수 있습니다. 그러나 일반적으로 – 아니요.

에 대해서는 var(명시 적으로 언급 이후)하는도의 광대 한 합의 는 C # 커뮤니티 에 대한 사용은 var. 그것의 사용에 반대하는 주장은 일반적으로 오류에 기초한다 .


답변

찬성

귀하의 코드 :

for(std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

템플릿 종속 이름으로 인해 컴파일되지 않습니다.

이것은 올바른 구문입니다.

for( typename std::vector<T>::iterator it = x.begin(); it != x.end(); i++)

이제 타입 선언의 길이를 살펴보십시오. auto키워드가 소개 된 이유를 알려줍니다 . 이 :

for( auto it = x.begin(); it != x.end(); i++)

더 간결합니다. 그래서 이것은 전문가입니다.


범죄자

약간 조심해야합니다. 키워드를 사용 auto하면 선언 한 유형을 얻습니다.

예를 들면 다음과 같습니다.

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto it : v )
{
  ++ it;   // ops modifying copies of vector's elements
}

vs

std::vector< int > v{ 1, 2, 3, 4 };
for ( auto & it : v )   // mind the reference
{
  ++ it;   // ok, vector's elements modified
}

결론 : 예, 사용해야하지만 과용해서는 안됩니다. 어떤 사람들은 그것을 너무 많이 사용하는 경향이 있으며 다음 예와 같이 어디서나 자동차를 사용합니다.

auto i = 0;

vs

int i = 0;


답변

예, 당신은해야합니다! auto유형을 지우지 않습니다. “알지 못하는”경우에도 x.begin()컴파일러는 형식을 잘못 사용하면 오류를 알고보고합니다. 또한를 map사용 하여 에뮬레이트 하는 것은 드문 일이 아니므로 vector<pair<Key,Value>>사용하는 코드 auto가 두 사전 표현 모두에서 작동합니다.


답변

예, auto기본 규칙으로 사용해야합니다 . 명시 적으로 유형을 지정하는 것보다 원시 이점이 있습니다.

  • 컴파일러가 이미 알고있는 것을 입력하지는 않습니다.
  • 변수 유형이 리턴 값 유형의 변경 사항을 “따라”따라갑니다.
  • 이렇게하면 로컬 변수 초기화에서 암시 적 변환 및 슬라이싱이 자동으로 발생하지 않습니다.
  • 템플릿에서 명시 적 유형 계산이 필요하지 않습니다.
  • 긴 이름을 가진 리턴 유형의 이름을 지정할 필요가 없습니다. (컴파일러 진단에서 복사하여 붙여 넣는 것)

이곳에서 선택하실 수 있습니다. 선택의 여지가없는 경우도 있습니다 :

  • 람다 유형과 같이 처리 할 수없는 유형의 변수를 선언 할 수 있습니다.

정확히 무엇을 알고 auto있다면 단점이 없습니다.


답변