From b2fd4a833b8b46bf5b330da0e39ee6f53ae1b888 Mon Sep 17 00:00:00 2001 From: Matrix-A <51079060+Matrix-A@users.noreply.github.com> Date: Tue, 2 Jan 2024 20:34:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E9=80=82=E7=94=A8=E8=8C=83?= =?UTF-8?q?=E5=9B=B4=E6=8F=8F=E8=BF=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../\347\254\25410\351\242\230/Matrix-A.cpp" | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/Matrix-A.cpp" "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/Matrix-A.cpp" index 2c48fcc0..86d3cbce 100644 --- "a/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/Matrix-A.cpp" +++ "b/src/\347\276\244\345\217\213\346\217\220\344\272\244/\347\254\25410\351\242\230/Matrix-A.cpp" @@ -109,6 +109,51 @@ void for_each_member(const T& agg, Fn&& fn) { } } +/* +T 类型的对象的列表初始化的效果是: + +1. 如果花括号初始化列表 包含指派初始化器列表,并且 T 不是引用类型,那么 T 必须是聚合类。由指派初始化器列表中的指派符组成的标识符序列必须是 T 的非静态数据成员组成的标识符序列的子序列。进行聚合初始化。 +(C++20 起) +2. 如果 T 是聚合类且花括号初始化列表 在不含指派初始化器列表的情况下(C++20 起)拥有单个(可有 cv 限定的)相同类型或派生类型的元素,那么从该元素初始化对象(对于复制列表初始化为复制初始化,对于直接列表初始化为直接初始化)。 +3. 否则,如果 T 是字符数组且初始化列表拥有单个类型适当的字符串字面量元素,那么照常从字符串字面量初始化数组。 +4. 否则,如果 T 是聚合类型,那么进行聚合初始化。 +5. 否则,如果花括号初始化列表 列表为空,且 T 是拥有默认构造函数的类类型,那么进行值初始化。 +6. 否则,如果 T 是 std::initializer_list 的特化,那么该 T 对象会以如下方式初始化。 +7. 否则,以两个阶段考虑 T 的构造函数: +7.1 检验所有接受 std::initializer_list 作为它的唯一实参,或如果剩余实参都具有默认值则为它的首个实参的构造函数,并通过重载决议与单个 std::initializer_list 类型的实参进行匹配。 +7.2 如果上一个阶段未产生匹配,那么 T 的所有构造函数都参与针对由花括号初始化列表 的各元素所组成的实参集的重载决议,它会受到只允许非窄化转换的限制。如果这个阶段为复制列表初始化产生的最佳匹配是 explicit 构造函数,那么编译失败(注意:简单复制初始化中完全不考虑 explicit 构造函数)。 +... +*/ + +/* +* 使用 { { detail::Anything{} } ... } 初始化成员的匹配顺序: +* 1. 不适用,无指派初始化器 +* 2. 适用 +* 3. 不适用 +* 4. 适用,聚合初始化(如果为空类,会产生初始化失败,因为参数个数1,需要参数个数为0) +* 5. 不适用,花括号初始化列表不为空 +* 6. 适用 +* 7.1 适用,优先考虑接受 std::initializer_list 作为它的唯一实参的构造函数 +* 7.2 适用,优先匹配到复制构造或移动构造,如果存在 +* 其他:不可能到后续匹配 +*/ + +/* +* 因此聚合类成员的适用范围 +* 1. 基础类型 +* 2. 聚合类型 +* 3. 非聚合类型,但是拥有接受 std::initializer_list 作为它的唯一实参的构造函数 +* 4. 非聚合类型,不存在接受 std::initializer_list 作为它的唯一实参的构造函数,但存在移动或复制构造函数,且不存在其他接受单一实参的构造函数 +*/ + +/* +* 注: 适用 mqb方案 表示使用 { detail::Anything{}... } 初始化成员 +* +* 已知特殊情况 +* 1. 成员为空类且聚合类型对象,不适用,因为参数过多(mqb方案适用这种情况,因为会直接转为对应的对象) +* 2. 存在空基类的聚合类型对象,不适用,因为基类需要一个"{}"进行初始化(mqb方案也不使用,存在一个Anything用于初始化基类)(详见花括号消除) +*/ + int main() { auto print = [](const auto& member) { if constexpr (!requires { std::cout << member; }) {