2016-06-29 3 views
3

가끔 getter가 반환 한 값 안에 중첩 된 getter가 일부 속성이 있는지 찾는 작업이 있습니다.Getter 내부에서 중첩 된 getter 결과를 균등하게 처리하는 가장 좋은 방법은

for (const auto& label: labels) 
    for (const auto& artist: label.artists()) 
    if (artist.name = "Arcade Fire") 
     return true; 
return false; 

범위이 할 수있는 가장 좋은 방법은 무엇입니까 : 고전 C++는 같은 것입니까?

labels| transform (&Label::artists) | join | transform(&Artist::name) | join | find_if_fn([](){/*...*/}) ; 

하지만 대신이 클래스 작성해야 .member_fn의 부분적으로 있기 때문에 (아주 긴 : I는 다음과 같이 작동 할 수 있습니다 생각?. member_fn을 이 할 수있는 짧은 방법이 있나요

+0

range-v3을 모르므로 ([link] (https://ericniebler.github.io/range-v3/) 제외), 입력 예제의 내부 루프를 다음으로 대체 할 수 있습니다. std :: find_if, 모든 아티스트를 평평하게하는 데는 하나의 조인 만 필요하므로 이름을 확인할 수 있습니다. 또한, find_if_fn() 람다는 이름을 얻을 수 있으므로 두 번째 변환은 더 이상 필요하지 않습니다. 변형 (& Label :: artists) | 가입 | find_if_fn ([] (const Artist & a) {return a.name == "The Smiths";});'. 이것은 실제로 의미가 있습니까? – stefaanv

+0

예, std :: find_if를 사용할 수 있었지만 제 코드에서는 섞지 않고 std :: some_alg를 선호하지 않습니다. – NoSenseEtAl

+0

그냥 for와 std :: alg 사이에 옵션이있을 때를 명확히하기 위해 alg을 고른다. 나는 그것들을 섞지 않는다. – NoSenseEtAl

답변

2

using namespace ranges; 
auto rng = labels | view::transform(&Label::artists) | view::join; 
return find(rng, "Arcade Fire", &Artist::name) != end(rng); 

는 매우 간단한 방법으로 일을 가져옵니다 view::filter 배합 : 나는이 생각합니다.

조금 더 어둡지 만 비슷한 성능을 보입니다. "foo가 있습니까?"에서 일반화하는 방법도 상당히 명확합니다. "모든 것을 돌려 보내라."