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

Bri*_*ian 19 c++ templates c++11

更具体地讲,假设我写template<class Pointer> class Foo,我要声明一个typedef类里面的那个类型*p,如果必须p是类型Pointer.

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

typename std::iterator_traits<Pointer>::reference
Run Code Online (Sandbox Code Playgroud)

这种方法的缺点是,如果Pointer是一些自定义迭代器类型并且作者忘记扩展std::iterator或以其他方式定义特化,它将不起作用std::iterator_traits.

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

decltype(*Pointer())
Run Code Online (Sandbox Code Playgroud)

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

decltype(**(Pointer*)0)
Run Code Online (Sandbox Code Playgroud)

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

我们可以做得更好吗?

chr*_*ris 22

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

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

decltype(*std::declval<Pointer>())
Run Code Online (Sandbox Code Playgroud)

  • 我错过了什么,或者不需要`*`?`decltype(*的std :: declval <指针>())` (3认同)