하나의 장점 std::begin
과 std::end
그들이 외부 클래스에 대한 표준 인터페이스를 구현하기위한 확장 점 역할을한다는 것입니다.
CustomContainer
범위 기반 for 루프 또는 템플릿 함수와 함께 클래스 를 사용 하고 기대 .begin()
하고 .end()
메소드를 사용하려면 해당 메소드를 구현해야합니다.
클래스가 이러한 메소드를 제공하는 경우 문제가되지 않습니다. 그렇지 않은 경우 수정해야합니다 *.
예를 들어 외부 라이브러리, 특히 상업용 및 비공개 소스 라이브러리를 사용할 때 항상 가능한 것은 아닙니다.
이러한 상황에서, std::begin
그리고 std::end
하나는 클래스 자체를 수정하는 것이 아니라 무료 기능을 과부하없이 반복자 API를 제공 할 수 있기 때문에, 편리.
예 :count_if
반복자 쌍 대신 컨테이너를 취하는 함수 를 구현한다고 가정하십시오 . 이러한 코드는 다음과 같습니다.
template<typename ContainerType, typename PredicateType>
std::size_t count_if(const ContainerType& container, PredicateType&& predicate)
{
using std::begin;
using std::end;
return std::count_if(begin(container), end(container),
std::forward<PredicateType&&>(predicate));
}
이제이 custom과 함께 사용 count_if
하려는 클래스의 경우 해당 클래스를 수정하는 대신 두 개의 무료 함수 만 추가하면됩니다.
이제 C ++에는
ADL ( Argument Dependent Lookup) 이라는 메커니즘 이있어 이러한 접근 방식이 훨씬 유연 해집니다.
간단히 말해 ADL은 컴파일러가 규정되지 않은 함수 (예 : begin
대신 네임 스페이스가없는 함수)를 해석 할 때 std::begin
인수의 네임 스페이스에 선언 된 함수도 고려한다는 의미입니다. 예를 들면 다음과 같습니다.
namesapce some_lib
{
// let's assume that CustomContainer stores elements sequentially,
// and has data() and size() methods, but not begin() and end() methods:
class CustomContainer
{
...
};
}
namespace some_lib
{
const Element* begin(const CustomContainer& c)
{
return c.data();
}
const Element* end(const CustomContainer& c)
{
return c.data() + c.size();
}
}
// somewhere else:
CustomContainer c;
std::size_t n = count_if(c, somePredicate);
이 경우에는 그 자격을 갖춘 이름은 중요하지 않습니다 some_lib::begin
및 some_lib::end
이후 - CustomContainer
에 some_lib::
너무, 컴파일러에 그 오버로드를 사용합니다 count_if
.
그것은 또한 필요에 대한 이유 using std::begin;
와 using std::end;
에서 count_if
. 이것은 우리가 자격이 사용할 수 있도록 begin
하고 end
, 따라서 ADL을 허용 하고
컴파일러가 선택할 수 있도록 std::begin
하고 std::end
다른 대안을 찾을 수 없을 때.
우리는 쿠키를 먹고 쿠키를 가질 수 있습니다. 즉 컴파일러가 표준 쿠키로 대체 할 수있는 동안 begin
/의 사용자 정의 구현을 제공 할 수있는 방법이 end
있습니다.
몇 가지 참고 사항 :
같은 이유로, 거기에 다른 유사한 기능은 다음과 같습니다 std::rbegin
/를 rend
,
std::size
하고 std::data
.
다른 답변에서 언급했듯이 std::
버전에는 기본 배열에 대한 과부하가 있습니다. 유용하지만 위에서 설명한 내용의 특별한 경우입니다.
std::begin
템플릿 코드를 작성할 때는 특히 템플릿을보다 일반적으로 사용하기 때문에 친구를 사용하는 것이 좋습니다. 템플릿이 아닌 경우 해당되는 경우 방법을 사용할 수도 있습니다.
추신 : 나는이 게시물이 거의 7 세라는 것을 알고 있습니다. 중복으로 표시된 질문에 대답하고 싶었고 여기에 ADL에 대한 답변이 없다는 것을 발견했기 때문에 나는 그것을 보았습니다.