我编写了这个 C++17 代码,并希望它能开箱即用。
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void,
std::output_iterator_tag
>
{
friend class boost::iterator_core_access;
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
auto dereference() const { return proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};
我试图通过设置我的迭代器的成员 typedefsvalue_type
和reference
to来匹配所有标准 OutputIterators 的行为void
(因为这些类型对于operator*
不返回引用的迭代器来说毫无意义)。
In file included from prog.cc:2:
/opt/wandbox/boost-1.63.0/clang-head/include/boost/iterator/iterator_facade.hpp:333:50: error: cannot form a reference to 'void'
static result_type apply(Reference const & x)
^
看起来 Boost 正在尝试将生成operator*
的签名硬编码为reference operator*() const
. 也就是说,boost::iterator_facade
可以operator*()
通过简单地传递 ; 返回的任何内容来推断出正确的返回类型dereference()
。但由于某种原因,它只是不配合。
解决方案是什么?我不能proxy
作为基类的模板参数传递,因为proxy
尚未定义。我可以拉出proxy
一个详细的命名空间:
namespace detail {
struct proxy {
void operator= (char ch) { putc(ch, stdout); }
};
}
class putc_iterator : public boost::iterator_facade<
putc_iterator,
void,
std::output_iterator_tag,
detail::proxy
>
{
friend class boost::iterator_core_access;
auto dereference() const { return detail::proxy{}; }
void increment() {}
bool equal(const putc_iterator&) const { return false; }
};
但这似乎很尴尬,绝对是“不必要的”。
这是一个错误iterator_facade
吗?它是功能而不是错误吗?如果是后者,那么我应该如何使用它来创建 OutputIterators?
另外,一个小问题:即使我使用 detail 命名空间的解决方法也是“错误的”,因为std::is_same_v<putc_iterator::reference, detail::proxy>
当我想要的(与标准迭代器相同)是std::is_same_v<putc_iterator::reference, void>
.