寻找Boost转换迭代器的复合特征模式
Looking for a composite traits pattern for boost's transform iterators
设置
当您想让迭代器在返回之前迭代的迭代器时,boost::transform_iterator
就非常好。您通过它们传递了一个单一函数,该功能会转换基础迭代器的operator*()
的结果,然后转换迭代器返回:
template<typename Map>
struct iterator_transform_traits_map_second {
typedef typename Map::value_type value_type;
typedef typename Map::mapped_type result_type;
result_type& operator()( value_type& v) const {return v.second;}
const result_type& operator()(const value_type& v) const {return v.second;}
};
typedef
boost::transform_iterator<iterator_transform_traits_map_second>
transformed_iterator;
到目前为止,一切都很好。但是。
什么搞乱导致
您的同事喜欢这种闪亮的新工具,也开始使用它,很快有人在标题中收集到到目前为止您所提出的一切。这是我们的:
-
iterator_transform_traits_map_first
-
iterator_transform_traits_map_second
-
iterator_transform_traits_map_deref
(取消任何容器的条目) -
iterator_transform_traits_map_deref_second
(删除地图条目的second
) -
iterator_transform_traits_map_dynamic_cast
(执行dynamic_cast<>()
任何容器的条目) -
iterator_transform_traits_map_any_second
(在地图条目的second
上执行any_cast<>()
)
当然,这会遗漏许多有用的(因为还没有人需要它们),并且它根本不扩展/strong> 。我刚刚被任命编写一个迭代器,该迭代器会删除地图条目的second
并执行dynamic_cast<>()
,而我是我被拒绝只添加iterator_transform_traits_map_dynamic_cast_deref_second
并继续前进的人。
我想要的
相反,我正在尝试编写一些基本特征和一个编译时组成特征,允许将其中的几个命名为模板参数,然后简单地将其命名。理想情况下,我想要这样的东西:
typedef
boost::transform_iterator<
iterator_transform_traits< iter_transf_tr_second
, iter_transf_tr_deref
, iter_transf_tr_dynamic_cast<derived>
>
>
transformed_iterator;
我当前的想法是递归得出包装模板,并递归地调用所有特征,将输出从一个传递到下一个。十年前,我已经做了这样的事情,并且对如何做到这一点有一个基本想法。但是,我上次这样做的是步行。也就是说,我自己实现了所有模板元魔术。
当然,这很愚蠢,鉴于我们现在有了boost.mpl,boost.fusion等,所以我宁愿使用已经存在的东西。但是,在修补了一个下午之后,很明显,在完成此操作之前,我会有很多东西要学习。虽然我不反对学习所有这些,但我有一个喜欢我所做的事情的人,但他说他还是需要拉插头,因为有这个截止日期...我现在可以选择只有编写该死的iterator_transform_traits_map_dynamic_cast_deref_second
,复制许多已经腐烂了十年并建立在此上的代码,或提出一个干净的解决方案。
那是您进来的地方。
问题
您将如何实现此复合特征,以利用已经存在的内容?
平台
但是,有一个问题:我们在一个嵌入式平台上,并使用GCC 4.1.2,这意味着 c 03 , tr1 和 boost 1.52 。没有可变模板参数,没有decltype
和所有那些花哨的东西。
您去这里:
iterator_transform_traits.hpp
#include <boost/mpl/vector.hpp>
#include <boost/mpl/back.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/push_back.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/fusion/adapted/mpl.hpp>
#include <boost/fusion/container/vector/convert.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/ref.hpp>
template<typename IteratorTraitsSequence, typename Container>
class iterator_transform_traits
{
public:
struct type
{
private:
struct plcaholder_resolver
{
template<typename IteratorTraits, typename IteratorLambda>
struct apply
{
typedef typename boost::mpl::push_back<IteratorTraits,
typename boost::mpl::apply<typename boost::mpl::lambda<IteratorLambda>::type, typename boost::mpl::back<IteratorTraits>::type::result_type>::type>::type type;
};
};
struct begin_value
{
typedef typename Container::value_type result_type;
};
typedef typename boost::mpl::pop_front<typename boost::mpl::fold<IteratorTraitsSequence, boost::mpl::vector<begin_value>, plcaholder_resolver>::type>::type iterator_traits;
public:
typedef typename boost::mpl::front<iterator_traits>::type::value_type value_type;
typedef typename boost::mpl::back<iterator_traits>::type::result_type result_type;
public:
struct recursive_iterator_modifier
{
template<class> struct result;
template<class F, typename CurrentResult, typename IteratorTrait>
struct result<F(CurrentResult&, const IteratorTrait&)>
{
typedef typename IteratorTrait::result_type& type;
};
template<class F, typename CurrentResult, typename IteratorTrait>
struct result<F(const CurrentResult&, const IteratorTrait&)>
{
typedef const typename IteratorTrait::result_type& type;
};
template<class F, typename CurrentResult, typename IteratorTrait>
struct result<F(const boost::reference_wrapper<CurrentResult>&, const IteratorTrait&)>
{
typedef typename IteratorTrait::result_type& type;
};
template<typename CurrentResult, typename IteratorTrait>
typename IteratorTrait::result_type&
operator()(CurrentResult& modified, const IteratorTrait& it)
{
return (it(modified));
}
template<typename CurrentResult, typename IteratorTrait>
const typename IteratorTrait::result_type&
operator()(const CurrentResult& modified, const IteratorTrait& it)
{
return (it(modified));
}
template<typename CurrentResult, typename IteratorTrait>
typename IteratorTrait::result_type&
operator()(const boost::reference_wrapper<CurrentResult>& modified, const IteratorTrait& it)
{
return (it(modified.get()));
}
};
public:
result_type& operator()(value_type& v) const
{
return boost::fusion::fold(iterator_traits_vector_, boost::ref(v), recursive_iterator_modifier());
}
const result_type& operator()(const value_type& v) const
{
return boost::fusion::fold(iterator_traits_vector_, boost::ref(v), recursive_iterator_modifier());
}
private:
typedef typename boost::fusion::result_of::as_vector<iterator_traits>::type iterator_traits_vector;
iterator_traits_vector iterator_traits_vector_;
};
};
您像这样使用它:
#include <map>
#include <string>
#include <iostream>
#include <typeinfo>
#include "iterator_transform_traits.hpp"
template<typename Pair>
struct iterator_transform_traits_map_second {
typedef Pair value_type;
typedef typename Pair::second_type result_type;
result_type& operator()( value_type& v) const {return v.second;}
const result_type& operator()(const value_type& v) const {return v.second;}
};
template<typename Dereferenced>
struct iterator_transform_traits_deref {};
template<typename Dereferenced>
struct iterator_transform_traits_deref<Dereferenced*> {
typedef Dereferenced* value_type;
typedef Dereferenced result_type;
result_type& operator()( value_type& v) const {return *v;}
const result_type& operator()(const value_type& v) const {return *v;}
};
typedef std::map<std::string, std::string*> string_ptr_map;
typedef iterator_transform_traits<boost::mpl::vector<iterator_transform_traits_map_second<boost::mpl::_1>, iterator_transform_traits_deref<boost::mpl::_1> >, string_ptr_map>::type Transformer;
typedef boost::transform_iterator<Transformer, string_ptr_map::iterator> string_ptr_map_second_deref_iterator;
int main()
{
string_ptr_map map;
map["key1"] = new std::string("value1");
map["key2"] = new std::string("value2");
map["key3"] = new std::string("value3");
for(string_ptr_map_second_deref_iterator it(map.begin(), Transformer()), ite(map.end(), Transformer()); it != ite; ++it)
{
std::cout << *it << std::endl;
}
return 0;
}
现在一些信息:
- 每个
iterator_transform_trait
必须在value_type
上模板,他将作为参数而不是在容器上接收,否则您无法自动链接它们。 - 使用
boost::mpl
和boost::fusion
有很多很少的元编程操作,我希望元功能名称足够明确,随时提出任何问题 - 您需要使用
mpl
序列作为模板参数,因为您无法访问C 11和Variadic模板。 - 这是一个在线编译版本:http://rextester.com/ziyg56999
- 这是一个有趣的练习,使我感到头疼:)
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 特征命名访问向量段
- 将特征矩阵的向量设置为0
- 特征:模板函数中矩阵的平面图
- basic_string的前导/尾部不区分空格的特征
- 特征 3 类的模板专用化
- 算术复合运算符重载为非成员
- 特征 c++:复矩阵的面积双曲正切(atanh)
- C++ 中的特征向量计算
- C++模板函数中的初始化 - 新的初始值设定项表达式列表被视为复合表达式
- 根据C++标准的定义实现"is_similar"类型特征
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- 时间复杂度 当具有复合数据类型(如元组或对)时?
- 有没有办法找到特征矩阵系数的中值?
- HDF5Cpp 扩展复合数据集超板问题
- 如何将高维数据映射到特征类型?
- 用推广make_shared和make_unique的方法复合指针特征类
- 寻找Boost转换迭代器的复合特征模式