иногда у меня возникает задача выяснить, есть ли у какого-то вложенного метода get в значении, возвращенном методом getter, какое-либо свойство.
классический с ++ будет что-то вроде:
for (const auto& label: labels)
for (const auto& artist: label.artists())
if (artist.name = "Arcade Fire")
return true;
return false;
Каков наилучший способ сделать это с диапазонами?
Я думаю, что-то вроде этого может работать:
labels| transform (&Label::artists) | join | transform(&Artist::name) | join | find_if_fn([](){/*...*/}) ;
Но это довольно долго (частично потому, что вместо .member_fn вы должны написать Class: member_fn.
Есть ли более короткий способ сделать это?
Я думаю это:
using namespace ranges;
auto rng = labels | view::transform(&Label::artists) | view::join;
return find(rng, "Arcade Fire", &Artist::name) != end(rng);
выполняет работу довольно простым способом. view::filter
формулировка:
using namespace ranges;
auto rng = labels | view::transform(&Label::artists) | view::join |
view::filter([](const Artist& a){ return a.name() == "Arcade Fire"; });
return !empty(rng);
Это немного сложнее, но, вероятно, имеет аналогичную производительность. Также довольно ясно, как обобщить это из «Есть ли foo?» «Вернуть все фоос».
Других решений пока нет …