C++ C+中的CTAD和指定初始值设定人+;20

C++ C+中的CTAD和指定初始值设定人+;20,c++,c++20,designated-initializer,ctad,C++,C++20,Designated Initializer,Ctad,在这篇文章中,我已经说明了关于CTAD和指定初始值设定项的混淆,但是我对一个非常类似的代码片段有另一个混淆 模板 构造我的\u对{ 国际优先; 浮秒; }; 模板 my_pair(ts…)->my_pair; int main(){ 我的_对x{.second=20.f}; static_assert(std::is_same_v);//失败请参见作为起点。我们有相同的初始三个候选者: template <class T=int, class U=float> struct my_p

在这篇文章中,我已经说明了关于CTAD和指定初始值设定项的混淆,但是我对一个非常类似的代码片段有另一个混淆

模板
构造我的\u对{
国际优先;
浮秒;
};
模板
my_pair(ts…)->my_pair;
int main(){
我的_对x{.second=20.f};
static_assert(std::is_same_v);//失败请参见作为起点。我们有相同的初始三个候选者:

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
的类型是
U

聚合扣减候选项是最佳候选项(只有聚合扣减候选项和扣减指南是可行的,聚合扣减候选项更专业),因此我们最终得到了
my\u pair


完成CTAD后,我们现在重新开始并有效地执行

my_pair<int, float> x{.second = 20.f};
为什么?我们还没有聚合扣减候选项,但我们仍然有扣减指南…这是可行的。它为我们提供了
my\U pair
。也就是说,一旦您填写了
U
的默认模板参数,
my\U pair


这就是为什么gcc给了你你看到的行为-它只是没有为聚合实现CTAD,而是给了你旧的行为。

演绎指南确实把水弄糊涂了,但我最终得到了
my_pair
。根据你的回答(和我的逻辑思维),我不应该…。因此,为了解决帖子中的问题。
首先
被推断为
float
是一个编译器错误。@kawillzocken添加了一个更新来解释为什么你最终会得到
my_pair
。这不是一个编译器错误,而是一个编译器尚未实现这一功能。GCC 9.1、Clang 9和VS 2019 16.1都实现了CTAD和指定的初始值设定项,没有一个实现了聚合的CTAD。但只有GCC首先将其推断为浮点。因此,至少有一个编译器存在错误。GCC有忽略指定项的记录。
my_pair<int, float> x{.second = 20.f};
my_pair{.second = 20.f};