std::iterator_traits用于Microsoft标准库中的积分类型
std::iterator_traits for integral types in Microsoft standard library
我有一个模板函数,它需要专门用于迭代器。所以我所做的是:
template <typename T>
void function2(T whatever, typename std::iterator_traits<T>::pointer) // ... iterator
template <typename T>
void function2(T whatever, ...) // ... non-iterator
template <typename T>
void function(T whatever) {
function2(whatever, NULL);
}
我遇到了一堵墙,因为Microsoft标准库专门为所有数字类型(bool
、char
、int
、float
…)提供std::iterator_traits
。它这样做使得reference
和pointer
是非void
,尽管事实上operator*
和operator->
都不能在这些类型上调用。
好的,我可以检查std::iterator_traits<T>::category
是否以一些更复杂的模板机制为代价导出std::input_iterator
(实际上我认为std::forward_iterator
在我的情况下更合适)。
然而,我有兴趣知道:
- 为什么他们为不符合迭代器概念的类型定义
iterator_traits
(即使输出迭代器至少需要一元operator*
,这些类型都没有 - 他们这样做是否违反了C++规范?并不是说微软不会到处违反它,但如果他们违反了,我会对编译器特定的解决方案感到满意,如果他们显然没有
- 总的来说,它可行吗?
std::iterator_traits<T>::pointer
似乎总是存在,但未定义,这会导致错误,而不是SFINAE
其他功能[res.on.functions]
[…]
2特别是,在以下情况下,影响是不明确的:
- 对于在实例化模板组件时用作模板参数的类型,如果该类型不实现适用的"需求"子条款的语义
为了使用iterator_traits<T>
,T
必须是迭代器。如果不是,则行为是未定义的。在编译时无法检测类型T
是否是迭代器。这在理论上甚至是不可能的,因为一个类型被允许支持与迭代器相同的运算符和typedef,因此实现的泛型iterator_traits<T>
可以在没有任何错误或警告消息的情况下实例化,但具有完全不同的含义。
仔细想想,由于您的评论阐明了合理的猜测就足够了,我认为您最好使用SFINAE和enable_if
来检测核心操作(一元*
和前缀++
),只有在满足这些条件的情况下才使用std::iterator_traits<T>::pointer
。
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- Microsoft Visual C++2010使用的C++类型
- 模板类中的尾随返回类型(GNU和Microsoft编译器之间的矛盾)
- 为什么Microsoft有两种类型的字符集?
- std::iterator_traits用于Microsoft标准库中的积分类型
- 适用于Microsoft Visual C++2008和R2007b的Mex类型
- 在Microsoft Visual C++中,光线跟踪器应该是什么类型的项目