如何在C++中获取任意 (STL) 输出迭代器的"assignable type"
How to obtain "assignable type" for an arbitrary (STL) output iterator in C++
C++ 标准要求将 std::iterator_traits<OutputIterator>
中的 typedef value_type
设置为 void
对于类型为 OutputIterator
的输出迭代器。尽管如此,对于给定的输出迭代器类型 OutputIterator
推断出在形式表达式中o
的可接受类型(不引用任何隐式转换)是完全合理的(在我的代码中是绝对必需的)
*it = o
其中it
是类型 OutputIterator
的对象。
理想情况下,我想使用 TMP 定义一个模板类my_iterator_traits
它定义了一个 typedef assignable_type
,这样my_iterator_traits<OutputIterator>::assignable_type
就会等于 decltype( o )
。有什么建议如何实现这一目标吗?
如果我通过定义模板专用化来枚举所有可能的 STL 迭代器类型,我什至不知道如何实现这一点。例如,以下代码无法编译,因为编译器无法推断模板参数T
:
template <typename Iterator> struct my_iterator_traits;
//[...]
//Does NOT compile, compiler cannot deduce type T
template <typename T> struct my_iterator_traits<std::vector<T>::iterator>
{
typedef typename std::vector<T>::value_type assignable_type;
//Another option, but I think not so clean:
//typedef T assignable_type;
};
编辑:这是我遇到问题的情况的草图(没有上下文)。建议要在二进制级别编辑容器的元素。对象first
是一个(输入)迭代器,它允许我访问已知大小(在本例中为 2 字节)的输入元素。我想通过接受单字节(输出)对象的输出迭代器result
将它们写入"二进制输出"。即,我不想指定输出迭代器的"单字节类型"应该是什么。(准-)法典:
const typename my_iterator_traits<OutputIterator>::assignable_type* ptr;
for( size_type i = 0; i < n; ++i, ++first )
{
ptr = reinterpret_cast<const typename my_iterator_traits<OutputIterator>::assignable_type*>( &( *first ) );
*result = ptr[0]; ++result;
*result = ptr[1]; ++result;
}
我担心如果没有reinterpret_cast
,可能会出现某些隐式转换会改变二进制结构的情况。我只想将位复制到目标,无论目标是什么以及如何通过输出迭代器提供的抽象接口访问它。唯一的要求是可以通过输出迭代器逐字节访问目标。
您的问题一般无法回答。
例如,下面是一个输出迭代器,虽然它在技术上只需要一种类型来operator=
,但实际上采用任何类型:
template<class OS>
struct ostream_proxy {
void* v;
void(*f)(void*, OS&);
template<class O>
friend O& operator<<(O& o, ostream_proxy p) {
p.f(p.v, o);
return o;
}
template<class X, class pX = typename std::decay_t<X>::type*>
ostream_proxy( X&& x ):
v(&x),
f(
[](void* px, OS& os) {
os << &static_cast<pX>(px);
}
)
{}
};
template<class OS>
std::ostream_iterator<ostream_proxy<OS>> it_out(OS& os) {
return {os};
}
template<class OS, class CharT>
std::ostream_iterator<ostream_proxy<OS>> it_out(OS& os, const CharT* delim) {
return {os, delim};
}
现在上面我很懒,我用代理类型使用了std::ostream_iterator
。 但是,输出迭代器上的operator=
重载或成为template
运算符是合法的。 如果是这种情况,则输出迭代器不会接受"一种没有转换的类型"。
(一个不那么懒惰/黑客的版本会重新实现ostream_iterator<>
有一个template operator=
,并且只写出任何类型。 在我看来,这将是std::ostream_iterator<void>
的一个很好的实现,就像std::less<void>
(又名std::less<>
)一样)。
检查是否有办法将给定类型分配给迭代器很容易,但在一般情况下,确定哪种类型涉及"无转换"是不可能的。 在特定情况下,有无数的黑客攻击。
像大多数"给定一个函数对象,给我它的签名"一样,这个问题假设有一个固定类型,或者应该有一个固定类型,涉及。 输出迭代器具有可用于加载它们的有效表达式,而不是特定类型。
- 集合上的输出迭代器:assign和increment迭代器
- 在静态库中使用输出迭代器时出现链接器错误
- 在插入容器之前转换输出迭代器
- 根据 boost::iterator_facade 定义基于代理的输出迭代器
- C++:为什么输出迭代器不支持比较操作?
- 输入迭代器可以重复读取,而输出迭代器只能写入一次
- 是C 正向/BIDI/随机迭代器总是输出迭代器
- stl风格的算法:如何管理输出迭代器
- 如何在C++中获取任意 (STL) 输出迭代器的"assignable type"
- 无法复制到输出迭代器
- 如何在C++中输出迭代器
- 要写入输出迭代器的模板成员函数
- 输入和输出迭代器
- std::transform 中的输入迭代器和输出迭代器来自同一个容器是否安全?
- 使用输出迭代器不起作用的通用函数示例
- 仅移动输入和输出迭代器
- 用Python生成器替换c++ STL输出迭代器
- 使用先前已移动的输出迭代器调用move()是标准的c++吗?
- STL映射输出迭代器查找值
- 输入迭代器+输出迭代器+X=正向迭代器