1
這裏是基於脫Implement a Range Adaptor with arguments一系列適配器的例子:如何實現與升壓的範圍適配器:: joined_range
#include <boost/range/join.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <vector>
#include <list>
#include <iterator>
#include <iostream>
template <typename Range, typename Index>
class permutation_range :
public boost::iterator_range<
boost::permutation_iterator<
typename boost::range_iterator<Range>::type,
typename boost::range_iterator<Index>::type>>
{
using value_type = typename boost::range_value<Range>::type;
using replaced_iterator = boost::permutation_iterator<
typename boost::range_iterator<Range>::type,
typename boost::range_iterator<Index>::type>;
using base_t = boost::iterator_range<replaced_iterator>;
public:
permutation_range(Range& r, Index& i)
: base_t(replaced_iterator(boost::begin(r), boost::begin(i)),
replaced_iterator(boost::end(r), boost::end(i)))
{}
};
template <typename Range, typename Index>
permutation_range<Range, Index>
permutation(Range& r, Index& i)
{
return permutation_range<Range, Index>(r, i);
}
int main()
{
std::vector<int> v1{99, 1, 99, 2, 99, 3};
std::list<int> indexer{1, 3, 5};
boost::copy(permutation(v1, indexer),
std::ostream_iterator<int>(std::cout, " "));
}
輸出
我想適應以上使用boost::joined_range。換句話說,取兩個向量,然後將它們加入permutation_range
內的一個較長範圍。這個想法很簡單:
例這將輸出2 4 6
:
int main()
{
std::vector<int> v1{1, 2, 3};
std::vector<int> v2{4, 5, 6};
std::list<int> indexer{1, 3, 5};
boost::copy(permutation(v1, v2, indexer),
std::ostream_iterator<int>(std::cout, " "));
}
我所有的努力,到目前爲止已經在一個巨大的編譯器錯誤的列表結束後,我還沒有顯示嘗試,因爲我可能是離開。我不知道這是否可能,但有誰能幫我解決這個問題嗎?
最後編輯(方案一點點黑客得到的範圍內的基類初始化之前)
#include <boost/range/join.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/iterator_range.hpp>
#include <boost/iterator/permutation_iterator.hpp>
#include <vector>
#include <list>
#include <iterator>
#include <iostream>
template <typename R1, typename R2>
struct initialize_me_first
{
initialize_me_first(typename boost::range::joined_range<const R1, const R2> j)
: j_range(j)
{}
typename boost::range::joined_range<const R1, const R2> j_range;
};
template <typename Range1, typename Range2, typename Index>
class permutation_range :
public initialize_me_first<Range1, Range2>,
public boost::iterator_range<
boost::permutation_iterator<
typename boost::range_iterator<
boost::range::joined_range<Range1, Range2>>::type,
typename boost::range_iterator<Index>::type>>
{
using value_type = typename boost::range_value<Range1>::type;
using replaced_iterator = boost::permutation_iterator<
typename boost::range_iterator<
boost::range::joined_range<Range1, Range2>>::type,
typename boost::range_iterator<Index>::type>;
using base_t = boost::iterator_range<replaced_iterator>;
using init = initialize_me_first<Range1, Range2>;
public:
permutation_range(const Range1& r1, const Range2& r2, const Index& i)
: init(boost::join(r1, r2)),
base_t(replaced_iterator(boost::begin(init::j_range),
boost::begin(i)),
replaced_iterator(boost::end(init::j_range),
boost::end(i)))
{}
};
template <typename Range1, typename Range2, typename Index>
permutation_range<const Range1, const Range2, const Index>
permutation(const Range1& r1, const Range2& r2, const Index& i)
{
return permutation_range<const Range1,
const Range2,
const Index>(r1, r2, i);
}
int main()
{
std::vector<int> v1{1, 2, 3};
std::vector<int> v2{4, 5, 6};
std::list<int> indexer{1, 3, 5};
boost::copy(permutation(v1, v2, indexer),
std::ostream_iterator<int>(std::cout, " "));
}
謝謝,我也意識到如果我想保留'permutation(v1,v2,indexer)'語法,我可以在'permutation'內部粘貼'boost :: join'。然而,我最初的目標是改變'permutation_range'使用'boost :: join'(不知道這是否可能)。 – 2012-07-24 22:13:10
這會更困難。你的'permutation_range'需要有一個它創建的連接範圍的副本 - 它需要爲它創建的'replaced_iterator'對象傳遞相同的值'r'。在基類初始化之前,該範圍必須存在。這是可以解決的,但是你也會在參數列表的* middle *中出現一個有效的「可選」參數('v2')的語法複雜性。如果調用者想要加入範圍,請讓調用者對此負責,並保持界面簡單並專注於一件事情。 – 2012-07-24 22:21:09
關於界面的好處,非常感謝您的幫助。在您的評論之後,我能夠想出一些東西(請參閱EDIT),但是,如何在基類初始化之前讓範圍存在? – 2012-07-24 23:13:23