【发布时间】:2017-08-15 14:37:08
【问题描述】:
是否可以从迭代器类型中检测容器类型?
例如,
#include<traits>
int main(){
static_assert(std::is_same<
container_of<std::vector<double>::iterator>::type, std::vector<double>>{});
static_assert(std::is_same<
container_of<std::list<int>::iterator>::type, std::list<int>>{});
}
(当然,某些迭代器类型不会给出容器(或不给出唯一容器),例如原始指针或流迭代器,但在这些情况下它可能会软 SFINAE 失败。)
第一次尝试是
template<class T, template<class> class Cont> Cont<T> aux(typename Cont<T>::iterator it);
template<class Iterator> struct container_of{
using type = decltype(aux(Iterator{}));
};
但是,它不起作用,因为编译器无法检测到T 的类型(它不在可扣除的上下文中)。
动机:我想检测一个迭代器的关联容器是否有.data()成员。
【问题讨论】:
-
快速回答:检查 .data() 成员的存在将比 container_of trait 更容易实现。
-
这是完全不可能的,永远不可能。迭代器类型只是某个类中的嵌套类型,或者可能只是没有嵌套在任何地方的类型。如果有的话,没有办法恢复它嵌套在哪个类中。
-
您可以为 known 容器/迭代器类型编写特征。动机有点不清楚。
data()对迭代器没有用处,你需要一个容器对象来调用它。 -
我认为他试图推断底层容器是连续的。
-
@n.m.我知道。重点如下。实际上可能检查一个容器是否是连续的。这是因为,实际上,
.data()成员的存在会泄露这一点。然而,这个技巧不能用于迭代器,即使在原则上显然也是如此。
标签: c++11 iterator containers sfinae typetraits