【问题标题】:type-erased C++ output iterator类型擦除的 C++ 输出迭代器
【发布时间】:2012-05-29 06:43:35
【问题描述】:

如何从输出迭代器中擦除类型为std::insert_iteratorstd::back_insert_iterator?是否可以使用 boost any_iterator 这样做?

#include <boost/range.hpp>
#include <boost/range/detail/any_iterator.hpp>
#include <vector>

typedef boost::range_detail::any_iterator<
    int, boost::incrementable_traversal_tag, int &, std::ptrdiff_t > It;

int main()
{
    std::vector<int> v;
    It outIt( v.begin() ); // compiles
    It inserter( std::back_inserter(v) ); // does not compile
    return 0;
}

【问题讨论】:

  • “擦除类型”是什么意思?
  • @EitanT:您应该查找“C++ 类型擦除”,但要简短定义“将具有通用接口的多种类型转换为具有相同接口的一种类型的过程”。 Boost::Any 就是典型的例子。
  • @JesseGood Aaa 我知道那是什么,我从来不知道它被称为“类型擦除”。哇!
  • @EitanT:这是一篇关于type erasure 的好文章,这是pattern
  • 我无法获得任何涉及boost::any_range 的代码来使用 GCC 4.6 或 4.7 进行编译。不仅标头 &lt;boost/range/any_range.hpp&gt; 有其自身的问题(例如,它不能独立工作,您需要在其之前包含 &lt;boost/range/concepts.hpp&gt;),但不知何故,在 4.7 中,当 std::iterator_traitsiterator 类型实例化时会出现问题any_range 实例化。如果我回避 that 那么any_range 的实现仍然存在问题,这可能与两阶段查找有关,也可能无关。抱歉,找不到更多信息。

标签: c++ boost stl type-erasure


【解决方案1】:

any_iterator 不适用于 输出迭代器,而 back_insert_iterator 就是这样(或者,就此而言,输入迭代器)。

back_insert_iterator 被定义为继承自iterator&lt;output_iterator_tag, void, void, void, void&gt; 即它的value_typereference_typedistance_typepointer_type 都是void,但any_iterator 希望能够通过其支持间接一个非空值的迭代器。也许命名为any_value_iterator 会更好;但它是一个detail 类模板。

【讨论】:

  • 谢谢。 Boost 中是否有替代方案?
  • 我不知道;问题是boost::iterator_facade 期望能够在课堂上定义operator[]operator-&gt;。使用boost::function 包装operator=(这是输出迭代器中唯一真正重要的部分)来定义自己应该不会太难。
【解决方案2】:

所以我使用 Boost 实现了自己的一个。

#include <boost/function_output_iterator.hpp>
#include <boost/function.hpp>

template < class T >
class AnyInserter : public boost::function_output_iterator< boost::function< void ( const T & value ) > >
{
private:
    typedef typename boost::function_output_iterator< boost::function< void ( const T & value ) > > BaseType;
    template < class OutIt > struct Insert
    {
        Insert( OutIt it ) : m_it(it) {}
        void operator () ( const T & value ) { m_it++ = value; }
        OutIt m_it;
    };
public:
    template < class OutIt >
        explicit AnyInserter( const OutIt & it ) : BaseType( Insert< OutIt >(it) ) {}
};

template < class OutIt >
    inline AnyInserter< typename OutIt::container_type::value_type >
    makeAnyInserter( const OutIt & it ) 
    {
        return AnyInserter< typename OutIt::container_type::value_type >(it);
    }

【讨论】:

  • 看起来不错。有一点是,您可能想要使用typename std::iterator_traits&lt;OutIt&gt;::value_type 而不是typename OutIt::container_type::value_type,以便您可以使用您的模板,例如原始指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-02
  • 2017-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多