关于实施标准::add_pointer的问题
A question regarding the implementation of std::add_pointer
From std::add_pointer
可能的实现
namespace detail {
template <class T>
struct type_identity { using type = T; }; // or use std::type_identity (since C++20)
template <class T>
auto try_add_pointer(int) -> type_identity<typename std::remove_reference<T>::type*>;
template <class T>
auto try_add_pointer(...) -> type_identity<T>;
} // namespace detail
template <class T>
struct add_pointer : decltype(detail::try_add_pointer<T>(0)) {};
上述(可能的(实现的说明如下:
如果 T 是引用类型,则提供成员类型定义类型 是指向引用类型的指针。
否则,如果 T 命名对象类型,则不是 cv- 或参考合格,或(可能符合 CV 标准(空隙类型,提供 成员类型定义类型,即类型 T*。
否则(如果 T 是符合 cv 或 ref 条件的函数类型(,则提供 成员类型定义类型,即类型 T。
在上面的(可能的(实现代码中,显然struct add_pointer
派生自detail::try_add_pointer<T>(0)
返回的类型。
从detail::try_add_pointer<T>
接受参数的重载返回的类型派生int
将成员typedef type
解析为上述三种可能性之一的逻辑是什么?具体来说,这如何解决T
是cv-
或ref-
限定函数类型的可能性?
关键在于了解detail::try_add_pointer<T>(0)
的重载解析是如何工作的。将T
代入detail::try_add_pointer
意味着生成始终包含至少一个成员的重载集(变量参数重载(。
在过载解决(SFINAE(期间是否丢弃int
的过载取决于将T
替换为typename std::remove_reference<T>::type*
的成功。当替换成功时,存在重载,并且重载分辨率与 0 的匹配度更好(省略号是与任何其他转换序列相比最差的匹配(。无论哪种方式,无论在重载解析中选取哪个重载,decltype(detail::try_add_pointer<T>(0))
都将解析为具有嵌套::type
成员的内容。
因此,让我们逐案分析:
"如果 T 是引用类型" - 让我们将其标记为
T = T2&
.那么std::remove_reference<T>::type
就T2
了.我们可以形成引用的类型也是我们可以形成指针的类型。所以std::remove_reference<T>::type*
格式正确(它是T2*
(,并且存在第一个重载。它在过载分辨率中被拾取。其返回类型的嵌套::type
为T2*
。"否则,如果 T 命名一个对象类型,一个不符合 cv 或 ref 限定的函数类型,或者一个(可能符合 cv 限定的(void 类型" - 在这种情况下,
std::remove_reference<T>::type
只是T
。我们可以形成指向上一个列表中的任何类型的指针,因此std::remove_reference<T>::type*
再次形成良好格式(并且T*
(。第一个重载再次存在,并以重载解析方式拾取。其返回类型的嵌套::type
为T*
。"否则(如果 T 是符合 cv 或 ref 条件的函数类型(" - 有趣的位。这说明了像
void (int) const&
.这里又std::remove_reference<T>::type
T
.但是我们不允许形成指向T
的指针,基本语言禁止这样做。因此std::remove_reference<T>::type*
格式不正确,对于此重载解析,将忽略第一个重载。只剩下第二个重载,它是重载分辨率拾取的重载。其返回类型的嵌套::type
为T
。
继承只是使用type_identity
包装器(已经需要形成有效的返回类型(以最小的工作量定义特征的一种方式。 重载技巧依赖于以下事实:std::remove_reference
是非引用类型的标识,并且(处理了引用(std::add_pointer<T>
是T*
,除非根本没有此类类型。 在这种情况下,SFINAE 会消除int
过载并选择...
(仅产生T
(。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- C++ - "!pointer"和"pointer == nullptr"的区别?
- 基于boost的程序的静态链接——zlib问题
- 从void Pointer(创建通用存储)铸造有什么问题