对于类型为value_type
的输出迭代器,C ++标准要求std::iterator_traits<OutputIterator>
中的typedef void
设置为OutputIterator
。尽管如此,对于给定的输出迭代器类型OutputIterator
来说,推断它是完全合理的(并且在我的代码中是绝对必需的),可接受的类型(不引用任何隐式转换)o
形式的表达
*it = o
其中it
是OutputIterator
类型的对象。
理想情况下,我想使用TMP定义一个定义typedef my_iterator_traits
的模板类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个字节)。我想把它们写成&#34;二进制输出&#34;通过输出迭代器result
接受单字节(输出)对象。即,我不想指定&#34;单字节类型&#34;输出迭代器应该是。 (准)代码:
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
,可能会发生一些隐式转换改变二进制结构的情况。我只想将这些位复制到目标,无论目标是什么以及如何通过输出迭代器提供的抽象接口来访问它。唯一的要求是可以通过输出迭代器逐字节访问目标。
答案 0 :(得分:2)
您的问题一般无法解答。
作为一个例子,这里是一个输出迭代器,虽然它在技术上只需要一种类型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
运算符。如果是这种情况,则没有&#34;一种没有转换的类型&#34;输出迭代器接受的。
(一个不太懒惰/ hacky的版本会重新实现ostream_iterator<>
以获得template operator=
,只需编写任何类型。在我看来,这将是一个很好的实现std::ostream_iterator<void>
,std::less<void>
(又名std::less<>
))。
很容易检查是否有办法将给定类型分配给迭代器,但确定哪种类型涉及&#34;没有转换&#34;在一般情况下是不可能的。在特定情况下,有无数的黑客攻击。
与大多数&#34;给定一个功能对象,给我签名&#34;这个问题假定是一个固定类型,或者应该是一个固定类型。输出迭代器具有可用于加载它们的有效表达式,而不是特定类型。