gpt4 book ai didi

c++ - 从 std::back_insert_iterator 派生?

转载 作者:行者123 更新时间:2023-11-30 04:37:58 26 4
gpt4 key购买 nike

我想派生自 std::back_insert_iterator为字符串类型创建一种过滤器,比如 back_xml_insert_iterator ,它将检查通过它传递的字符,寻找不能“裸”到 XML 流中的字符,例如 '"' , '&' , '<' , '>' , 和 '\'' , 并将即时插入其字符实体引用,例如 "&#34;"对于 '"' .

template<class StringType>
class back_xml_insert_iterator : public std::back_insert_iterator<StringType> {
typedef std::back_insert_iterator<StringType> base_type;
public:
typedef typename base_type::container_type container_type;
typedef typename StringType::value_type value_type;

explicit back_xml_insert_iterator( StringType &s ) : base_type( s ) { }

back_xml_insert_iterator& operator=( value_type c ) {
switch ( c ) {
case '"':
case '&':
case '\'':
case '<':
case '>':
char buf[10];
this->container->append( "&#" );
this->container->append( itoa( c, buf ) );
this->container->push_back( ';' );
break;
default:
this->container->push_back( c );
}
return *this;
}
};

这编译得很好。当我创建一个实例时,我确认调用了构造函数,但是我的 operator=()永远不会被调用。我认为这是因为继承了 operator*()返回 back_insert_iterator&而不是 back_xml_insert_iterator&所以back_insert_iterator::operator=()被称为而不是我的(因为 operator=() 不是,也不可能是 virtual)。

如果是这样,那么似乎不可能从 back_insert_iterator 派生出以一种有用的方式。

如果我改为创建自己的 back_insert_iterator_base类如:

template<class ContainerType,class DerivedType>
class back_insert_iterator_base :
public std::iterator<std::output_iterator_tag,void,void,void,void> {
public:
typedef ContainerType container_type;

DerivedType& operator*() {
return *static_cast<DerivedType*>( this );
}

DerivedType& operator++() {
return *static_cast<DerivedType*>( this );
}

DerivedType& operator++(int) {
return *static_cast<DerivedType*>( this );
}

protected:
back_insert_iterator_base( ContainerType &c ) : container( &c ) {
}

ContainerType *container;
};

并从中派生出:

template<class StringType>
class back_xml_insert_iterator :
public back_insert_iterator_base< StringType, back_xml_insert_iterator<StringType> > {
// ... as before ...
};

然后 back_xml_insert_iterator按需工作。那么是否有可能从 std::back_insert_iterator 推导出来?是否按预期工作?

更新

这是我想使用 back_xml_insert_iterator 的方式.首先,会有辅助函数:

template<class StringType> inline
back_xml_insert_iterator<StringType> back_xml_inserter( StringType &s ) {
return back_xml_insert_iterator<StringType>( s );
}

然后写一个to_xml()功能将是微不足道的:

template<class InputStringType,class OutputStringType> inline
void to_xml( InputStringType const &in, OutputStringType *out ) {
std::copy( in.begin(), in.end(), back_xml_inserter( *out ) );
}

最佳答案

您不应该尝试继承在设计时并未考虑继承的类。通常,您不应该继承标准容器或迭代器。请注意,在大多数情况下,迭代器的使用首先是在不需要类型层次结构的模板中。

通常最好通过提供仿函数或实现您自己的迭代器来从外部添加功能——这不应该很复杂。如果你真的想实现自己的迭代器,你可以看看 boost 中的迭代器适配器库。

关于c++ - 从 std::back_insert_iterator 派生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3488670/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com