CTAD 和 C++20 中的指定初始值设定项
CTAD and designated initializers in C++20
我已经在这个问题中说明了CTAD与指定初始值设定项的混淆,但我对非常相似的代码片段有另一个混淆
template <typename int_t=int, typename float_t=float>
struct my_pair {
int_t first;
float_t second;
};
template<typename ... ts>
my_pair(ts...) -> my_pair<ts...>;
int main() {
my_pair x{.second = 20.f};
static_assert( std::is_same_v<decltype(x.first), int> ); //FAILS <- its deduced to float
static_assert( std::is_same_v<decltype(x.second), float> );
}
似乎演绎指南导致first
的类型被推导出float
,即使我没有在指定的初始值设定项中给出明确的.first
。演绎指南显然只关心初始值设定项中的顺序,无论关键字(.second
(。扣除指南应该对此很聪明,还是应该有一个"指定的扣除指南"?
请参阅 https://godbolt.org/z/cm6Yi7 上的示例
把这个答案作为一个起点。我们有相同的初始三个候选人:
template <class T=int, class U=float>
struct my_pair {
T first;
U second;
};
// default constructor
template <class T=int, class U=float>
auto __f() -> my_pair<T, U>;
// copy candidate
template <class T=int, class U=float>
auto __f(my_pair<T, U>) -> my_pair<T, U>;
// deduction guide
template <class... T>
auto __f(T...) -> my_pair<T...>;
聚合扣除候选项基于我们提供的实际初始值设定项列表或指定初始值设定项列表,而不是聚合的实际基础成员。我们的指定初始值设定项列表{.second = 20.f}
因此我们的总扣除候选值变为:
// aggregate deduction candidate
template <class T=int, class U=float>
auto __f(U) -> my_pair<T, U>;
模板参数始终来自主类模板,因此我们从那里引入默认模板参数。候选参数来自初始值设定项列表,second
的类型为U
。
合计扣除候选者是最佳候选者(只有合计扣除候选和扣除指南可行,合计扣除候选者更专业(,所以我们最终得到my_pair<int, float>
。
完成CTAD后,我们现在重新开始并有效地做
my_pair<int, float> x{.second = 20.f};
这有效,并导致x.first
从{}
初始化。
CTAD 骨料最近才通过(两个月前在 2019 年 7 月的科隆会议上(。在该功能之前,这仍然是格式良好的:
my_pair{.second = 20.f};
为什么?我们还没有汇总扣除候选者,但我们仍然有扣除指南......这是可行的。它给了我们my_pair<float>
.也就是说,my_pair<float, float>
一旦您填写了默认模板参数U
.
这就是为什么 gcc 给你你看到的行为 - 它只是还没有为聚合实现 CTAD,而是给你旧的行为。
相关文章:
- 用C++20 fmt限制结果的总大小
- 如何在C++20中创建模板别名的推导指南
- 实施具有 C++20 概念的配对概念
- C++20概念:需要运算符重载
- 为什么在C++20中对lambdas使用"std::bind_front"
- 填孔方法需要20分钟以上
- c++20[[no.unique_address]]中的新功能是什么
- 如何在 C++20 计时中为日期添加天数?
- 必须为 C++20 协程帧保留多少内存?
- C++20 概念:如何在"requires"子句中引用类名?
- 在C++中随机生成 20 个非重复数字
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- C++20 协程:需要一个使用 co_yield 的函数
- 主.cpp:18:20:错误:从"int*"转换为"int"会失去精度 [-fa
- 将 C++20 范围与istreambuf_iterator一起使用
- 使用文件系统时仍然需要链接到带有 C++20 的 stdc++fs?
- 在 C++20 中将多个范围适配器连接到一个范围中
- C++20 使用 Visual Studio 编译模块:不编译或导入 ixx 文件
- 标准::累积C++20版本
- CTAD 和 C++20 中的指定初始值设定项