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

时间:2013-01-23 01:52:24

标签: c++ templates c++11

更具体地说,假设我正在撰写template<class Pointer> class Foo,并且我想在类中声明typedef类型*p如果p属于输入Pointer

在C ++ 03中,据我所知,唯一的方法是使用类似

的方法
typename std::iterator_traits<Pointer>::reference

此方法的缺点是,如果Pointer是某个自定义迭代器类型且作者忘记扩展std::iterator或以其他方式定义std::iterator_traits专门化,则它将无效。

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

decltype(*Pointer())

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

decltype(**(Pointer*)0)

我尝试了这个,但它确实有效,但后来我认为它看起来有点不确定因为它涉及空引用的解引用,因此可能不符合标准。

我们可以做得更好吗?

4 个答案:

答案 0 :(得分:22)

你对解除引用空指针持谨慎态度,但事实是它在这里没关系! <{1}}不评估其操作数,因此在内部取消引用空指针是完全有效的。

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

<utility>

答案 1 :(得分:2)

在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

这是demo;

答案 2 :(得分:0)

执行具有SFINAE回退的迭代器特征以解除引用。

创建一个返回std::decay<T>&然后取消引用的模板函数,而不是取消引用null。

答案 3 :(得分:0)

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

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