최근에 저는 매우 어려운 const-correctness 컴파일러 오류를 수정하려고했습니다. 처음에는 Boost.Python 내에 여러 단락 템플릿 구토 오류가있었습니다.std :: begin 및 R-values
그러나 이것은 중요하지 않습니다. C++ 11 std::begin
과 std::end
반복자 함수는 R 값을 얻기 위해 오버로드되지 않습니다. std::begin
의
정의 (들)은 다음과 같습니다에는 R 값/유니버설 참조 과부하가 없기 때문에 당신이 그것에게 R-값을 전달하면
는template< class C >
auto begin(C& c) -> decltype(c.begin());
template< class C >
auto begin(const C& c) -> decltype(c.begin());
그래서, 당신은 const를 반복자를 얻을.
그럼 왜 신경 써야하나요? 예를 들어 "view", "proxy"또는 "slice"또는 다른 컨테이너의 하위 반복자 범위를 나타내는 일부 컨테이너 유형과 같은 "범위"컨테이너 유형이있는 경우에는 R 값 의미를 사용하고 임시 슬라이스/범위 객체에서 비 const 반복기를 가져옵니다. 그러나 std::begin
을 사용하면 std::begin
이 항상 R 값의 const 반복기를 반환하기 때문에 운이 나빠집니다. 이것은 C++ 11 프로그래머가 종종 C++ 11이 R 값을주기 전날에 좌절했던 오래된 문제입니다. 즉 임시 직원 문제는 항상 const
이라는 바인딩입니다. c
우리는 그렇지 C::const_iterator
과 C::iterator
을 얻을 일정한 경우,
template <class C>
auto begin(C&& c) -> decltype(c.begin());
이 방법 :
그럼, 왜로 정의되지 std::begin
된다.
처음에는 그 이유가 안전 때문이라고 생각했습니다. 당신이 std::begin
에 임시 전달과 같이하는 경우 :
auto it = std::begin(std::string("temporary string")); // never do this
... 당신은 잘못된 반복자를 얻을 것입니다. 그러나 그때 나는이 구현이 여전히 존재한다는 것을 깨달았다. 위의 코드는 잘못된 const -iterator를 반환하며, 역 참조 할 때 segfault가됩니다.
그래서 std::begin
이이 아닌가요? R 값 (정확하게는 Universal Reference)이되도록 정의 된 이유는 무엇입니까? 과부하가 두 개있는 이유는 무엇입니까 (const
에 하나, non-const
에 하나).
'std :: forward (c)'을 잊어 버렸습니다. –
Columbo
이 경우 문제가 될지 잘 모르겠다 -이 경우 중요한 것은 'c'는'const'이거나'C &&'가'C &'로 변한 후에 영향을받지 않는 문제이다. – Siler
컨테이너가 ref-qualifier로'begin '을 오버로드하여 반환 된 반복자 유형을 객체 인수의 값 범주에 종속되게 만듭니다. 그러나 맞지 않는 시범 목적을 위해. – Columbo