Я предлагаю использовать диапазон усиления (алгоритмы и адаптеры) для простоты использования, вы написали бы:
boost::copy(
data | transformed(makeT) | filtered(validate) /* | indirected */,
std::back_inserter(queue));
Вот полный рабочий пример этого:
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/optional.hpp>
#include <vector>
#include <deque>
typedef boost::optional<int> T;
typedef std::deque<T> Q;
static T makeT(int i)
{
if (i%2) return T();
else return i;
}
static bool validate(const T& optional)
{
return (bool) optional; // select the optional that had a value set
}
int main()
{
static const int data[] = { 1,2,3,4,5,6,7,8,9 };
Q q;
using boost::adaptors::filtered;
using boost::adaptors::transformed;
// note how Boost Range elegantly supports an int[] as an input range
boost::copy(data | transformed(makeT) | filtered(validate), std::back_inserter(q));
// demo output: 2, 4, 6, 8 printed
for (Q::const_iterator it=q.begin(); it!=q.end(); ++it)
{
std::cout << (*it? "set" : "unset") << "\t" << it->get_value_or(0) << std::endl;
}
return 0;
}
Обновление
С небольшой помощью из этого ответа: Используйте boost :: опционально вместе с boost :: adapters :: indirected
Теперь я включаюэлегантная демонстрация использования адаптера диапазона indirected
для немедленного вывода очереди (разыменование опций):
Обратите внимание, что для (интеллектуальных) типов указателей будет очевидно, не нужно указывать специализацию pointee<>
.Я считаю, что это по замыслу: optional<> is not, and does not model, a pointer
#include <boost/range.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/optional.hpp>
namespace boost {
template<typename P> struct pointee<optional<P> > {
typedef typename optional<P>::value_type type;
};
}
typedef boost::optional<int> T;
static T makeT(int i) { return i%2? T() : i; }
static bool validate(const T& optional) { return (bool) optional; }
int main() {
using namespace boost::adaptors;
static int data[] = { 1,2,3,4,5,6,7,8,9 };
boost::copy(data | transformed(makeT)
| filtered(validate)
| indirected,
std::ostream_iterator<int>(std::cout, ", "));
}