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

lx0bsm1f  于 2022-12-05  发布在  其他
关注(0)|答案(4)|浏览(158)

To be more specific, suppose I am writing template<class Pointer> class Foo and I want to declare a typedef inside the class for the type that *p would have if p were of type Pointer .
In C++03, as far as I am aware, the only way to do this is with something like

typename std::iterator_traits<Pointer>::reference

The disadvantage of this method is that it won't work if Pointer is some custom iterator type and the author forgot to extend std::iterator or otherwise define a std::iterator_traits specialization.
In C++11, my colleague suggested

decltype(*Pointer())

But this won't work if Pointer is not default-constructible, so he amended this to

decltype(**(Pointer*)0)

I tried this, and it worked, but then I thought that it looked a bit iffy because it involves the dereference of a null pointer, and thus might not be standards-compliant.
Can we do better?

osh3o9ms

osh3o9ms1#

你对空指针的解引用非常谨慎是对的,但事实上这里是可以的!decltype不计算它的操作数,所以在里面解引用空指针是完全有效的。
然而,正确的解决方案是std::declval,它是在C++11中的<utility>中引入的:

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

kuhbmx9i2#

在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;

brccelvz

brccelvz3#

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

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

bvjxkvbb4#

使用SFINAE回退到取消引用来执行迭代器特性。
创建一个返回std::decay<T>&的模板函数,然后对它进行解引用,而不是解引用null。

相关问题