boost range

本文介绍了Boost.Range库,其算法与标准库类似,但以范围为首个参数,如boost::copy()等,可避免迭代器使用错误。还提到了适配器,可看作过滤器,返回新范围,如boost::adaptors::filter()等,且适配器可嵌套使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.Algorithms

Boost.Range is library that, on the first sight, provides algorithms similar to those provided by the standard library. For example, you will find the function boost::copy(), which does the same thing as std::copy(). However, std::copy() expects two parameters while boost::copy() expects a range.

You can think of a range as two iterators that refer to the beginning and end of a group of elements that you can lterate over. Because all containers support iterators, every container can be thought of as a range. Since all algorithms from Boost.Range expect a range as a first parameter, a container like std::vector can be passed directly. You don't have to call begin() and end() and then pass two iterators separately. This protects you from mistakes such as passing the begin and end iterator in the wrong order or passining iterators that belong to two different containers.

#include <boost/range/algorithm.hpp>
#include <array>
#include <iostream>

int main() {
  std::array<int, 6> a{{0, 1, 0, 1, 0, 1}};
  std::cout << boost::count(a, 0) << std::endl;
  return 0;
}

输出 3

All algorithms from Boost.Range requirre the first parameter to be a range. An object of type std::array can be passed to boost::count() directly since containers are ranges. Because boost::count() is equivalent to std::count(), you must pass in the value that the elements in the range will be compared with.

#include <boost/range/algorithm.hpp>
#include <boost/range/numeric.hpp>
#include <array>
#include <iterator>
#include <iostream>

int main() {
  std::array<int, 6> a{{0, 1, 2, 3, 4, 5}};
  boost::random_shuffle(a);
  boost::copy(a, std::ostream_iterator<int>{std::cout, ","});
  std::cout << std::endl << *boost::max_element(a) << std::endl;
  std::cout << boost::accumulate(a, 0) << std::endl;
  return 0;
}

boost::random_shffle() works like std::random_shuffle(), changing the order of elements in a range randomly.  boost::copy works like std::copy. boost::max_element() and boost::accumulate() work like the identically named algorithms from the standard library. Like std::max_element(), boost::max_element() returns an iterator to the element with the greatest number.

 

#include <boost/range/algorithm_ext.hpp>
#include <array>
#include <deque>
#include <iterator>
#include <iostream>

int main() {
  std::array<int, 6> a{{0, 1, 2, 3, 4, 5}};
  std::cout << std::boolalpha << boost::is_sorted(a) << std::endl;
  std::deque<int> d;
  boost;:push_back(d, a);
  boost::remove_erase(d, 2);
  boost::copy_n(d, 3, std::ostream_iterator<int>{std::cout, ","});
  return 0;
}

boost::is_sorted() tests whether elements in a range are sorted. A predicate can be passed as the second parameter to boost::is_sorted() to check, for example, whether a range is sorted in descending order.

boost::push_back() expects as its first parameter a container and its second parameter a range.

boost::remove_erase() removes the number 2 from d. This algorithm combines a call to the function std::remove() and a call to the member function erase() of the respective container.

 

2. Adaptors

You can think of adaptors as filters. They return a new range based on another range. Data isn't necessarily copied. Since a range is just a pair of iterators, an adaptor returns a new pair. The pair can still be used to iterate over the original range but may, for example, skip certain required.

The difference between algorithms and adaptors is that  algorithms iterate over a range and process data, while adaptors return a new range - new iterators - that determines what elements the iteration returns.

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <array>
#include <iterator>
#include <iostream>

int main() {
  std::array<int, 6> a{{0, 5, 2, 1, 3, 4}};
  boost::copy(boost::adaptors::filter(a, [](int i) { return i > 2;}), std::ostream_iterator<int>{std::cout, ","});
  return 0;
}

boost::adaptors::filter() expects as its first parameter a range to filter and as its second parameter a predicate. boost::adaptors::filter() does not change the range a. it returns a new range. Since a range isn't much different from a pair of iterators, the new range also refers to a. However, the iterators for the new range skip all numbers that are less than or equal 2.

 

#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <array>
#include <map>
#include <string>
#include <utility>
#include <iterator>
#include <iostream>

int main() {
  std::array<int, 3> a{{0, 1, 2}};
  std::map<std::string, int*> m;
  m.insert(std::make_pair("a", &a[0]));
  m.insert(std::make_pair("b", &a[1]));
  m.insert(std::make_pair("c", &a[2]));

  boost::copy(boost::adaptors::keys(m), std::ostream_iterator<std::string>{std::cout, ","});
  boost::copy(boost::adaptors::indirect(boost::adaptors::values(m)), std::ostream_iterator<int>{std::cout, ","});
  return 0;
}

uses adaptors, boost::adaptors::keys() and boost::adaptors::values() to access keys and values in a container of type std::map. It also shows how adaptors can be nested. Because m stores pointers to the values to be printed, rather than the values themselves, the range returned by boost::adaptors::values() is passed to boost::adaptors::indirect(). This adaptor can always be used when a range consists of pointers, but an iteratorion should return the values the pointers refer to.

转载于:https://www.cnblogs.com/sssblog/p/11177980.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值