在当前的C++中,类ostream_iterator的设计如下:
// excerpted from the standard C++
template<class T, ...>
class ostream_iterator
{
public:
ostream_iterator(ostream_type&);
...
ostream_iterator<T,...>& operator =(const T&);
...
};
Run Code Online (Sandbox Code Playgroud)
对我来说,这种设计并不是最理想的.因为用户在声明ostream_iterator时必须指定类型T:ostream_iterator<int> oi(cout);事实上,cout可以将任何类型的对象作为其参数,而不是仅使用一种类型.这是一个明显的限制.
// Below is my own version
// doesn't need any template parameter here
class ostream_iterator
{
public:
ostream_iterator(ostream_type&);
...
// define a template member function which can take any type of argument and output it
template<class T>
ostream_iterator<T,...>& operator =(const T&);
...
};
Run Code Online (Sandbox Code Playgroud)
现在,我们可以使用它如下:
ostream_iterator oi(cout);
Run Code Online (Sandbox Code Playgroud)
我认为它比它更通用,更优雅
ostream_iterator<int> oi(cout);
Run Code Online (Sandbox Code Playgroud)
我对吗?
看来你可能是对的。
让我们看看是否可以构造一个不需要模板参数的 ostream_iterator。
迭代器通过将值复制到其中来工作,因此*iter = x; ++iter;
迭代器通过使operator*返回自身并且++iter在不改变任何状态的情况下返回自身来作弊。“魔力”在于执行输出的operator=。
“cout”必须是 ostream* 类型的类成员。它需要是一个指针,因为迭代器必须是可分配的,因此我们将成员(称为 os)分配给传入的流的地址。
所以我们会这样重载operator=:
template< typename T >
our_ostream_iterator& operator=( const T& t )
{
(*os) << t;
if( delim )
(*os) << delim;
return *this;
}
Run Code Online (Sandbox Code Playgroud)
请注意,模板化的operator=不应重载比模板更专业的operator=(our_ostream_iterator const&)。
您仍然需要元素类型的模板,因此我们将其称为our_basic_ostream_iterator
ostream_iterator 仍将保留其元素类型的模板类。因此:
template< typename E, typename TR=char_traits<E> >
class our_basic_ostream_iterator : public std::iterator< /*traits here*/ >
{
public:
typedef E element_type;
typedef TR traits_type;
typedef basic_ostream< E, TR > stream_type;
private:
stream_type * os;
const E* delim;
public:
our_basic_ostream_iterator( stream_type s, const E* d = nullptr ) :
os( &s ), delim( d )
{
}
our_basic_ostream_iterator& operator++() { return *this; }
our_basic_ostream_iterator operator++(int) { return *this; }
our_basic_ostream_iterator& operator*() { return *this; }
template< typename T >
our_basic_ostream_iterator& operator=( const T& t ); // as above
};
Run Code Online (Sandbox Code Playgroud)
然后当然
typedef our_basic_ostream_iterator<char> our_ostream_iterator;
typedef our_basic_ostream_iterator<wchar_t> our_wostream_iterator;
Run Code Online (Sandbox Code Playgroud)
但所有这些的缺点是,上述内容并不符合迭代器的所有属性,因此它可以传递给任何需要前向迭代器的算法/类。为什么?因为这样的算法应该能够调用iterator_traits来提取元素类型,而上面的类不包含元素类型。
这会导致使用迭代器的算法出现编译时错误,并且可能很难找出原因。
| 归档时间: |
|
| 查看次数: |
1341 次 |
| 最近记录: |