C# LINQ 提供了優雅的鏈式查詢語法。C++14 通過模板、類型推導、運算符重載可實現類似風格,如 from(v) >> where(pred) >> to_vector()。
from_range包裝迭代器對,提供 front() 獲取當前元素,next() 推進迭代器。
template
struct from_range {
using value_type = typename iterator_traits::value_type;
TIterator current, upcoming, end;
from_range(TIterator b, TIterator e) : current(b), upcoming(b), end(e) {}
template
decltype(auto) operator>>(TRangeBuilder builder) const { return builder.build(*this); }
decltype(auto) front() const { return *current; }
bool next() { return upcoming == end ? false : (current = upcoming++, true); }
};
where_range 與構建器 where_builder接收上游範圍與謂詞,next() 跳過不滿足條件的元素。
template
struct where_range {
using value_type = typename TRange::value_type;
TRange range; TPredicate pred;
where_range(TRange r, TPredicate p) : range(r), pred(p) {}
template
decltype(auto) operator>>(TRangeBuilder b) const { return b.build(*this); }
decltype(auto) front() const { return range.front(); }
bool next() { while (range.next()) if (pred(range.front())) return true; return false; }
};
template
struct where_builder {
TPredicate pred;
where_builder(TPredicate p) : pred(p) {}
template
auto build(TRange r) { return where_range(r, pred); }
};
template
auto where(TPredicate p) { return where_builder(p); }
to_vector_builder將範圍物化為 vector。
struct to_vector_builder {
template
auto build(TRange r) {
vector res;
while (r.next()) res.push_back(r.front());
return res;
}
};
auto to_vector() { return to_vector_builder(); }
fromtemplate
auto from(const TContainer& c) {
return from_range(begin(c), end(c));
}
int main() {
int a[] = {1, 2, 3, 4};
auto v = from(a) >> where([](int n){ return n % 2 == 0; }) >> to_vector();
for (int x : v) cout << x << endl; // 輸出 2, 4
}
此實現展示了 C++14 通過表達式模板、完美轉發、運算符重載實現鏈式查詢的核心機制。雖無標準庫 LINQ 完善,但為理解範圍庫(Range-v3/C++20 Ranges)設計思想提供了極佳切入點。