C++11:如何获取指针或迭代器指向的类型

C++11: How to get the type a pointer or iterator points to?

本文关键字:迭代器 类型 指针 何获取 获取 C++11      更新时间:2023-10-16

更具体地说,假设我正在编写template<class Pointer> class Foo,并且我想在类中为*p类型声明一个typedef,如果p类型为Pointer类型。

据我所知,在 C++03 中,做到这一点的唯一方法是使用类似的东西

typename std::iterator_traits<Pointer>::reference

此方法的缺点是,如果Pointer是某种自定义迭代器类型,并且作者忘记扩展std::iterator或以其他方式定义std::iterator_traits专用化,则此方法不起作用。

在 C++11 中,我的同事建议

decltype(*Pointer())

但是如果Pointer不是默认可构造的,这将不起作用,所以他将其修改为

decltype(**(Pointer*)0)

我试过这个,它奏效了,但后来我认为它看起来有点不稳定,因为它涉及空指针的取消引用,因此可能不符合标准。

我们能做得更好吗?

您对取消引用空指针持谨慎态度是对的,但事实是这里没关系! decltype 不计算其操作数,因此取消引用内部的空指针是完全有效的。

然而,正确的解决方案是 std::declval ,在 C++11 中引入<utility>

decltype(*std::declval<Pointer>())

在 C++03 中,您可以编写一个简单的结构,它将从给定类型中删除所有指针:

template<typename T>
struct ActualType { typedef T type; };
template<typename T>
struct ActualType<T*> { typedef typename ActualType<T>::type type; };

如果您通过int*int**,那么最终ActualType<T>::type将归结为int

这是一个演示;

在 C++11 中,您可以使用std::remove_pointer

using PType = std::remove_pointer<Pointer>::type;

执行迭代器特征,SFINAE回退到取消引用。

与其取消引用 null,不如创建一个返回 std::decay<T>& 然后取消引用该模板函数。