const auto&
읽기 전용 작업을 수행하려면 충분합니다. 그러나 나는 부딪쳤다
for (auto&& e : v) // v is non-const
최근에 몇 번. 이것은 나를 궁금하게 만듭니다.
그것은 몇 가지 모호한 구석 경우에 비해, 전달 참조를 사용하여 약간의 성능 향상이 있음을 가능 auto&
또는 const auto&
?
( shared_ptr
모호한 코너 케이스에 대한 용의자)
즐겨 찾기에서 찾은 두 가지 예를 업데이트합니다 .
기본 유형을 반복 할 때 const 참조를 사용하는 단점이 있습니까?
범위 기반 for 루프를 사용하여 맵의 값을 쉽게 반복 할 수 있습니까?
질문에 집중하십시오 : 범위 기반 for 루프에서 auto &&를 사용하는 이유는 무엇입니까?
답변
내가 볼 수있는 유일한 장점은 시퀀스 반복기가 프록시 참조를 반환하고 상수가 아닌 방식으로 해당 참조에서 작업해야하는 경우입니다. 예를 들어 다음을 고려하십시오.
#include <vector>
int main()
{
std::vector<bool> v(10);
for (auto& e : v)
e = true;
}
vector<bool>::reference
에서 반환 된 rvalue가 상수 iterator
가 아닌 lvalue 참조에 바인딩되지 않기 때문에 컴파일되지 않습니다 . 그러나 이것은 작동합니다.
#include <vector>
int main()
{
std::vector<bool> v(10);
for (auto&& e : v)
e = true;
}
그런 사용 사례를 충족해야한다는 것을 알지 못한다면 나는 이런 식으로 코딩하지 않을 것입니다. 이 때문에 즉 나는 무상으로이 작업을 수행하지 않을 않습니다 당신이 뭘하는지 궁금해하는 원인 사람들. 그렇게했다면 이유에 대한 의견을 포함해도 괜찮습니다.
#include <vector>
int main()
{
std::vector<bool> v(10);
// using auto&& so that I can handle the rvalue reference
// returned for the vector<bool> case
for (auto&& e : v)
e = true;
}
편집하다
이 마지막 사례는 정말 이해하기 쉬운 템플릿이어야합니다. 당신은 루프가 항상 프록시 참조를 처리하는 알고있는 경우 auto
뿐만 아니라 작동합니다 auto&&
. 그러나 루프가 때때로 비 프록시 참조와 때로는 프록시 참조를 처리 할 때 auto&&
선택의 해결책이 될 것이라고 생각 합니다.
답변
범위 기반 루프 와 함께 auto&&
또는 범용 참조 를 사용 for
하면 얻은 내용을 캡처 할 수 있다는 이점이 있습니다. 대부분의 이터레이터의 경우 a T&
또는 a T const&
for some type을 얻을 수 있습니다 T
. 흥미로운 경우는 반복기를 역 참조하면 일시적인 결과가 발생하는 경우입니다. C ++ 2011은 완화 된 요구 사항을 얻었으며 반복기가 반드시 lvalue를 산출하는 데 필요한 것은 아닙니다. 범용 참조의 사용은에서 전달하는 인수와 일치합니다 std::for_each()
.
template <typename InIt, typename F>
F std::for_each(InIt it, InIt end, F f) {
for (; it != end; ++it) {
f(*it); // <---------------------- here
}
return f;
}
함수 개체를 f
처리 할 수 있습니다 T&
, T const&
그리고 T
다르게. 범위 기반 for
루프 의 본문이 달라야 하는 이유는 무엇 입니까? 물론, 범용 참조를 사용하여 유형을 추론 한 것을 실제로 활용하려면 그에 따라 전달해야합니다.
for (auto&& x: range) {
f(std::forward<decltype(x)>(x));
}
물론, 사용 std::forward()
은 이동할 반환 된 값을 수락한다는 의미입니다. 이런 객체가 내가 모르는 (아직?) 템플릿이 아닌 코드에서 많이 의미가 있는지 여부. 범용 참조를 사용하면 올바른 작업을 수행하기 위해 컴파일러에 더 많은 정보를 제공 할 수 있다고 상상할 수 있습니다. 템플릿 코드에서는 객체에 어떤 일이 발생해야하는지에 대한 결정을 내릴 수 없습니다.
답변
나는 거의 항상 auto&&
. 필요하지 않은데 왜 엣지 케이스에 물 릴까요? 입력하는 것도 더 짧아서 더 투명합니다. 를 사용하면 매번 정확히 auto&& x
임을 알 수 있습니다.x
*it