C++ 是否可以推断std::insert_迭代器包含的类型?
我有一个需要模板迭代器类型的函数 它当前取消对迭代器的引用以检查正在迭代的类型C++ 是否可以推断std::insert_迭代器包含的类型?,c++,iterator,sfinae,C++,Iterator,Sfinae,我有一个需要模板迭代器类型的函数 它当前取消对迭代器的引用以检查正在迭代的类型 template < typename Iterator > void func( Iterator i ) { // Inspect the size of the objects being iterated const size_t type_size = sizeof( *i ); ... } template void func(迭代器i) { //检查正在迭代的对象的大小 常量
template < typename Iterator >
void func( Iterator i )
{
// Inspect the size of the objects being iterated
const size_t type_size = sizeof( *i );
...
}
template
void func(迭代器i)
{
//检查正在迭代的对象的大小
常量大小类型大小=大小(*i);
...
}
我最近发现一些标准迭代器类型,例如std::insert_iterator
将*I
定义为对I
的简单引用
也就是说,sizeof(*i)
是迭代器本身的大小;与sizeof(i)
或sizeof(***i)
是否有一个通用的方式(支持C++ 03)来确定任何标准迭代器迭代的对象的大小或类型?
这就是我们要做的。typedef typename std::iterator\u traits::value\u type;
常数std::size\u t type\u size=sizeof(type);
编辑:这并非对所有输出迭代器都有效。我不确定您为什么想要输出迭代器的
value\u type
,因为无法从输出迭代器中提取值。但是,三个插入迭代器适配器都将value\u-type
定义为void
,并提供一个container\u-type
类型成员,因此如果T
的value\u-type
结果为void
,您可以返回到T::container\u-type
的值\u-type
(我所说的“value\u type
of”实际上是指std::iterator\u traits::value\u type
和std::iterator\u traits::value\u type
)
或者,您不能尝试使用输出迭代器,就好像它们有值:)
编辑:SFINAE不是必需的:(即使没有C++11的精确性)
模板结构帮助程序{typedef U type;};
//ostream*\u迭代器处理由Drew Dorman提供
模板
结构助手{typedef T type;};
模板
结构助手{typedef charT type;};
//原始存储迭代器仍然需要重写
//以及任何不定义容器类型的非标准输出迭代器。
模板结构辅助程序
{typedef typename std::iterator_traits::value_type;};
类型定义结构我的值类型
:公共助理{};
对于任何std::insert_iterator
,是否存在将该类型评估为void
的gcc错误?你的代码没有编译——给出了它试图计算sizeof(void)
@Drew Dormann的错误,如果这是你自己的迭代器类型,我怀疑你必须专门化iterator\u traits
,它才能知道值类型。这很奇怪,@ipc(后续)我对value\u type
有一个常见的误解。它被定义为从迭代器读取的类型。因此它对插入迭代器没有意义。(对不起,这也使得这个答案是错误的)我实际上希望插入类型,而不是提取类型。您的容器类型建议很有趣。我可能需要使用一些SFINAE魔法,因为原始指针是有效的迭代器,但没有定义类型def。@DrewDormann:std::iterator\u traits::value\u type应该是t
,但是,不?@DrewDormann,当然,这对ostream\u迭代器不起作用。对于这一点,你只是索尔。谢谢,你的解决方案成功了。我修复了一个输入错误,并添加了对iostream迭代器的支持。请考虑我的SIL。Dr.WordWordman:对丢失的类型名称感到抱歉,谢谢您修复它。我去掉了istream_迭代器,因为它应该总是有一个value_类型(它是一个输入迭代器),并添加了ostreambuf_迭代器。我没有添加raw_storage_iterator,通过搜索标准的output_iterator_标记,这是我所能知道的唯一其他标准输出迭代器。
typedef typename std::iterator_traits<Iterator>::value_type type;
const std::size_t type_size = sizeof(type);
template<typename U, typename T> struct helper {typedef U type;};
// ostream*_iterator handling courtesy Drew Dormann
template <typename T, typename charT, typename traits>
struct helper<void, std::ostream_iterator<T, charT, traits> > {typedef T type;};
template <typename charT, typename traits>
struct helper<void, std::ostreambuf_iterator<charT, traits> > {typedef charT type;};
// std::raw_storage_iterator still needs an override
// as well as any non-standard output iterators which don't define a container_type.
template<typename T> struct helper<void, T>
{typedef typename std::iterator_traits<typename T::container_type>::value_type type;};
typedef<typename It> struct my_value_type
: public helper<typename std::iterator_traits<It>::value_type, It> {};